Logo
~Sockets~
~Examples~
~Contact~


TcpSocket Class Reference
[Basic sockets]

Socket implementation for TCP. More...

#include <TcpSocket.h>

Inheritance diagram for TcpSocket:
Collaboration diagram for TcpSocket:

List of all members.


Public Member Functions

 TcpSocket (ISocketHandler &)
 Constructor with standard values on input/output buffers.
 TcpSocket (ISocketHandler &h, size_t isize, size_t osize)
 Constructor with custom values for i/o buffer.
 ~TcpSocket ()
bool Open (ipaddr_t ip, port_t port, bool skip_socks=false)
 Open a connection to a remote server.
bool Open (SocketAddress &, bool skip_socks=false)
bool Open (SocketAddress &, SocketAddress &bind_address, bool skip_socks=false)
bool Open (const std::string &host, port_t port)
 Open connection.
void OnConnectTimeout ()
 Connect timeout callback.
int Close ()
 Close file descriptor - internal use only.
void Send (const std::string &s, int f=0)
 Send a string.
void Sendf (const char *format,...)
 Send string using printf formatting.
void SendBuf (const char *buf, size_t len, int f=0)
 Send buffer of bytes.
virtual void OnRawData (const char *buf, size_t len)
 This callback is executed after a successful read from the socket.
virtual void OnWriteComplete ()
 Called when output buffer has been sent.
size_t GetInputLength ()
 Number of bytes in input buffer.
size_t ReadInput (char *buf, size_t sz)
 Read from input buffer.
size_t GetOutputLength ()
 Number of bytes in output buffer.
void OnLine (const std::string &line)
 Callback fires when a socket in line protocol has read one full line.
uint64_t GetBytesReceived (bool clear=false)
 Get counter of number of bytes received.
uint64_t GetBytesSent (bool clear=false)
 Get counter of number of bytes sent.
void OnSocks4Connect ()
 Socks4 specific callback.
void OnSocks4ConnectFailed ()
 Socks4 specific callback.
bool OnSocks4Read ()
 Socks4 specific callback.
void OnResolved (int id, ipaddr_t a, port_t port)
 Callback executed when resolver thread has finished a resolve request.
void OnSSLConnect ()
 Callback for 'New' ssl support - replaces SSLSocket.
void OnSSLAccept ()
 Callback for 'New' ssl support - replaces SSLSocket.
virtual void InitSSLClient ()
 This method must be implemented to initialize the ssl context for an outgoing connection.
virtual void InitSSLServer ()
 This method must be implemented to initialize the ssl context for an incoming connection.
void SetReconnect (bool=true)
 Flag that says a broken connection will try to reconnect.
bool Reconnect ()
 Check reconnect on lost connection flag status.
void SetIsReconnect (bool x=true)
 Flag to determine if a reconnect is in progress.
bool IsReconnect ()
 Socket is reconnecting.
void DisableInputBuffer (bool=true)
 Use this if you only use OnRawData to process received data.
void OnOptions (int, int, int, SOCKET)
 Called when a client socket is created, to set socket options.
void SetLineProtocol (bool=true)
 Called after OnRead if socket is in line protocol mode.
const std::string GetLine () const
 Get the unfinished line when using SetLineProtocol = true.
bool SetTcpNodelay (bool=true)
virtual int Protocol ()
 Returns IPPROTO_TCP or IPPROTO_SCTP.
void SetTransferLimit (size_t sz)
 Trigger limit for callback OnTransferLimit.
virtual void OnTransferLimit ()
 This callback fires when the output buffer drops below the value set by SetTransferLimit.

Protected Types

typedef std::list< OUTPUT * > output_l

Protected Member Functions

 TcpSocket (const TcpSocket &)
void OnRead ()
 Called when there is something to be read from the file descriptor.
void OnRead (char *buf, size_t n)
void OnWrite ()
 Called when there is room for another write on the file descriptor.
void InitializeContext (const std::string &context, const SSL_METHOD *meth_in=NULL)
 SSL; Initialize ssl context for a client socket.
void InitializeContext (const std::string &context, const std::string &keyfile, const std::string &password, const SSL_METHOD *meth_in=NULL)
 SSL; Initialize ssl context for a server socket.
void InitializeContext (const std::string &context, const std::string &certfile, const std::string &keyfile, const std::string &password, const SSL_METHOD *meth_in=NULL)
 SSL; Initialize ssl context for a server socket.
void UseCertificateChainFile (const std::string &filename)
 SSL; load certificate chain from file.
virtual SSL_CTX * GetSslContext ()
 SSL; Get pointer to ssl context structure.
virtual SSL * GetSsl ()
 SSL; Get pointer to ssl structure.
bool SSLNegotiate ()
 ssl; still negotiating connection.
const std::string & GetPassword ()
 SSL; Get ssl password.

Static Protected Member Functions

static int SSL_password_cb (char *buf, int num, int rwflag, void *userdata)
 SSL; Password callback method.

Protected Attributes

CircularBuffer ibuf
 Circular input buffer.

Private Member Functions

TcpSocketoperator= (const TcpSocket &)
void SendFromOutputBuffer ()
int TryWrite (const char *buf, size_t len)
 the actual send()
void Buffer (const char *buf, size_t len)
 add data to output buffer top

Private Attributes

bool m_b_input_buffer_disabled
uint64_t m_bytes_sent
uint64_t m_bytes_received
bool m_skip_c
 Skip second char of CRLF or LFCR sequence in OnRead.
char m_c
 First char in CRLF or LFCR sequence.
std::vector< char > m_line
 Current line in line protocol mode.
size_t m_line_ptr
char * m_buf
 temporary read buffer
output_l m_obuf
 output buffer
OUTPUTm_obuf_top
 output buffer on top
size_t m_transfer_limit
size_t m_output_length
size_t m_repeat_length
SSL_CTX * m_ssl_ctx
 ssl context
SSL * m_ssl
 ssl 'socket'
BIO * m_sbio
 ssl bio
std::string m_password
 ssl password
int m_socks4_state
 socks4 support
char m_socks4_vn
 socks4 support, temporary variable
char m_socks4_cd
 socks4 support, temporary variable
unsigned short m_socks4_dstport
 socks4 support
unsigned long m_socks4_dstip
 socks4 support
int m_resolver_id
 Resolver id (if any) for current Open call.
bool m_b_reconnect
 Reconnect on lost connection flag.
bool m_b_is_reconnect
 Trying to reconnect.

Static Private Attributes

static SSLInitializer m_ssl_init
static Mutex m_server_ssl_mutex
static std::map< std::string,
SSL_CTX * > 
m_client_contexts
static std::map< std::string,
SSL_CTX * > 
m_server_contexts

Classes

class  CircularBuffer
 Buffer class containing one read/write circular buffer. More...
struct  OUTPUT
 Output buffer struct. More...

Detailed Description

Socket implementation for TCP.

Definition at line 62 of file TcpSocket.h.


Member Typedef Documentation

typedef std::list<OUTPUT *> TcpSocket::output_l [protected]

Definition at line 121 of file TcpSocket.h.


Constructor & Destructor Documentation

TcpSocket::TcpSocket ( ISocketHandler h  ) 

Constructor with standard values on input/output buffers.

Definition at line 86 of file TcpSocket.cpp.

00086                                       : StreamSocket(h)
00087 ,ibuf(TCP_BUFSIZE_READ)
00088 ,m_b_input_buffer_disabled(false)
00089 ,m_bytes_sent(0)
00090 ,m_bytes_received(0)
00091 ,m_skip_c(false)
00092 ,m_line(Handler().MaxTcpLineSize())
00093 ,m_line_ptr(0)
00094 #ifdef SOCKETS_DYNAMIC_TEMP
00095 ,m_buf(new char[TCP_BUFSIZE_READ + 1])
00096 #endif
00097 ,m_obuf_top(NULL)
00098 ,m_transfer_limit(0)
00099 ,m_output_length(0)
00100 ,m_repeat_length(0)
00101 #ifdef HAVE_OPENSSL
00102 ,m_ssl_ctx(NULL)
00103 ,m_ssl(NULL)
00104 ,m_sbio(NULL)
00105 #endif
00106 #ifdef ENABLE_SOCKS4
00107 ,m_socks4_state(0)
00108 #endif
00109 #ifdef ENABLE_RESOLVER
00110 ,m_resolver_id(0)
00111 #endif
00112 #ifdef ENABLE_RECONNECT
00113 ,m_b_reconnect(false)
00114 ,m_b_is_reconnect(false)
00115 #endif
00116 {
00117 }

TcpSocket::TcpSocket ( ISocketHandler h,
size_t  isize,
size_t  osize 
)

Constructor with custom values for i/o buffer.

Parameters:
h ISocketHandler reference
isize Input buffer size
osize Output buffer size

Definition at line 126 of file TcpSocket.cpp.

00126                                                                 : StreamSocket(h)
00127 ,ibuf(isize)
00128 ,m_b_input_buffer_disabled(false)
00129 ,m_bytes_sent(0)
00130 ,m_bytes_received(0)
00131 ,m_skip_c(false)
00132 ,m_line(Handler().MaxTcpLineSize())
00133 ,m_line_ptr(0)
00134 #ifdef SOCKETS_DYNAMIC_TEMP
00135 ,m_buf(new char[TCP_BUFSIZE_READ + 1])
00136 #endif
00137 ,m_obuf_top(NULL)
00138 ,m_transfer_limit(0)
00139 ,m_output_length(0)
00140 ,m_repeat_length(0)
00141 #ifdef HAVE_OPENSSL
00142 ,m_ssl_ctx(NULL)
00143 ,m_ssl(NULL)
00144 ,m_sbio(NULL)
00145 #endif
00146 #ifdef ENABLE_SOCKS4
00147 ,m_socks4_state(0)
00148 #endif
00149 #ifdef ENABLE_RESOLVER
00150 ,m_resolver_id(0)
00151 #endif
00152 #ifdef ENABLE_RECONNECT
00153 ,m_b_reconnect(false)
00154 ,m_b_is_reconnect(false)
00155 #endif
00156 {
00157 }

TcpSocket::~TcpSocket (  ) 

Definition at line 163 of file TcpSocket.cpp.

References m_buf, m_obuf, and m_ssl.

00164 {
00165 #ifdef SOCKETS_DYNAMIC_TEMP
00166         delete[] m_buf;
00167 #endif
00168         // %! empty m_obuf
00169         while (m_obuf.size())
00170         {
00171                 output_l::iterator it = m_obuf.begin();
00172                 OUTPUT *p = *it;
00173                 delete p;
00174                 m_obuf.erase(it);
00175         }
00176 #ifdef HAVE_OPENSSL
00177         if (m_ssl)
00178         {
00179                 SSL_free(m_ssl);
00180         }
00181 #endif
00182 }

TcpSocket::TcpSocket ( const TcpSocket s  )  [protected]

Definition at line 958 of file TcpSocket.cpp.

00959 :StreamSocket(s)
00960 ,ibuf(0)
00961 {
00962 }


Member Function Documentation

bool TcpSocket::Open ( ipaddr_t  ip,
port_t  port,
bool  skip_socks = false 
)

Open a connection to a remote server.

If you want your socket to connect to a server, always call Open before Add'ing a socket to the sockethandler. If not, the connection attempt will not be monitored by the socket handler...

Parameters:
ip IP address
port Port number
skip_socks Do not use socks4 even if configured

Definition at line 185 of file TcpSocket.cpp.

Referenced by HttpGetSocket::DoConnect(), OnResolved(), Open(), HttpPutSocket::Open(), and HttpPostSocket::Open().

00186 {
00187         Ipv4Address ad(ip, port);
00188         Ipv4Address local;
00189         return Open(ad, local, skip_socks);
00190 }

bool TcpSocket::Open ( SocketAddress ad,
bool  skip_socks = false 
)

Definition at line 204 of file TcpSocket.cpp.

References Open().

00205 {
00206         Ipv4Address bind_ad("0.0.0.0", 0);
00207         return Open(ad, bind_ad, skip_socks);
00208 }

bool TcpSocket::Open ( SocketAddress ad,
SocketAddress bind_address,
bool  skip_socks = false 
)

Connecting();

Definition at line 211 of file TcpSocket.cpp.

References Socket::Attach(), closesocket, Socket::CopyConnection(), Socket::CreateSocket(), Errno, ISocketHandler::FindConnection(), SocketAddress::GetFamily(), SocketAddress::GetPort(), Socket::GetSocks4Host(), Socket::GetSocks4Port(), Socket::Handler(), INVALID_SOCKET, SocketAddress::IsValid(), Utility::l2ip(), Utility::l2string(), LOG_LEVEL_FATAL, LOG_LEVEL_INFO, ISocketHandler::LogError(), Open(), Reconnect(), Socket::SetCallOnConnect(), Socket::SetClientRemoteAddress(), Socket::SetCloseAndDelete(), StreamSocket::SetConnecting(), Socket::SetIsClient(), Socket::SetNonblocking(), Socket::SetRemoteAddress(), Socket::SetSocks4(), Socket::Socks4(), and StrError.

00212 {
00213         if (!ad.IsValid())
00214         {
00215                 Handler().LogError(this, "Open", 0, "Invalid SocketAddress", LOG_LEVEL_FATAL);
00216                 SetCloseAndDelete();
00217                 return false;
00218         }
00219         if (Handler().GetCount() >= Handler().MaxCount())
00220         {
00221                 Handler().LogError(this, "Open", 0, "no space left for more sockets", LOG_LEVEL_FATAL);
00222                 SetCloseAndDelete();
00223                 return false;
00224         }
00225         SetConnecting(false);
00226 #ifdef ENABLE_SOCKS4
00227         SetSocks4(false);
00228 #endif
00229         // check for pooling
00230 #ifdef ENABLE_POOL
00231         if (Handler().PoolEnabled())
00232         {
00233                 ISocketHandler::PoolSocket *pools = Handler().FindConnection(SOCK_STREAM, "tcp", ad);
00234                 if (pools)
00235                 {
00236                         CopyConnection( pools );
00237                         delete pools;
00238 
00239                         SetIsClient();
00240                         SetCallOnConnect(); // ISocketHandler must call OnConnect
00241                         Handler().LogError(this, "SetCallOnConnect", 0, "Found pooled connection", LOG_LEVEL_INFO);
00242                         return true;
00243                 }
00244         }
00245 #endif
00246         // if not, create new connection
00247         SOCKET s = CreateSocket(ad.GetFamily(), SOCK_STREAM, "tcp");
00248         if (s == INVALID_SOCKET)
00249         {
00250                 return false;
00251         }
00252         // socket must be nonblocking for async connect
00253         if (!SetNonblocking(true, s))
00254         {
00255                 SetCloseAndDelete();
00256                 closesocket(s);
00257                 return false;
00258         }
00259 #ifdef ENABLE_POOL
00260         SetIsClient(); // client because we connect
00261 #endif
00262         SetClientRemoteAddress(ad);
00263         int n = 0;
00264         if (bind_ad.GetPort() != 0)
00265         {
00266                 bind(s, bind_ad, bind_ad);
00267         }
00268 #ifdef ENABLE_SOCKS4
00269         if (!skip_socks && GetSocks4Host() && GetSocks4Port())
00270         {
00271                 Ipv4Address sa(GetSocks4Host(), GetSocks4Port());
00272                 {
00273                         std::string sockshost;
00274                         Utility::l2ip(GetSocks4Host(), sockshost);
00275                         Handler().LogError(this, "Open", 0, "Connecting to socks4 server @ " + sockshost + ":" +
00276                                 Utility::l2string(GetSocks4Port()), LOG_LEVEL_INFO);
00277                 }
00278                 SetSocks4();
00279                 n = connect(s, sa, sa);
00280                 SetRemoteAddress(sa);
00281         }
00282         else
00283 #endif
00284         {
00285                 n = connect(s, ad, ad);
00286                 SetRemoteAddress(ad);
00287         }
00288         if (n == -1)
00289         {
00290                 // check error code that means a connect is in progress
00291 #ifdef _WIN32
00292                 if (Errno == WSAEWOULDBLOCK)
00293 #else
00294                 if (Errno == EINPROGRESS)
00295 #endif
00296                 {
00297                         Attach(s);
00298                         SetConnecting( true ); // this flag will control fd_set's
00299                 }
00300                 else
00301 #ifdef ENABLE_SOCKS4
00302                 if (Socks4() && Handler().Socks4TryDirect() ) // retry
00303                 {
00304                         closesocket(s);
00305                         return Open(ad, true);
00306                 }
00307                 else
00308 #endif
00309 #ifdef ENABLE_RECONNECT
00310                 if (Reconnect())
00311                 {
00312                         Handler().LogError(this, "connect: failed, reconnect pending", Errno, StrError(Errno), LOG_LEVEL_INFO);
00313                         Attach(s);
00314                         SetConnecting( true ); // this flag will control fd_set's
00315                 }
00316                 else
00317 #endif
00318                 {
00319                         Handler().LogError(this, "connect: failed", Errno, StrError(Errno), LOG_LEVEL_FATAL);
00320                         SetCloseAndDelete();
00321                         closesocket(s);
00322                         return false;
00323                 }
00324         }
00325         else
00326         {
00327                 Attach(s);
00328                 SetCallOnConnect(); // ISocketHandler must call OnConnect
00329         }
00330 
00331         // 'true' means connected or connecting(not yet connected)
00332         // 'false' means something failed
00333         return true; 
00334 }

bool TcpSocket::Open ( const std::string &  host,
port_t  port 
)

Open connection.

Parameters:
host Hostname
port Port number

Definition at line 337 of file TcpSocket.cpp.

References Socket::Handler(), Utility::isipv4(), Utility::isipv6(), m_resolver_id, Open(), Socket::Resolve(), Socket::SetCloseAndDelete(), and Utility::u2ip().

00338 {
00339 #ifdef ENABLE_IPV6
00340 #ifdef IPPROTO_IPV6
00341         if (IsIpv6())
00342         {
00343 #ifdef ENABLE_RESOLVER
00344                 if (!Handler().ResolverEnabled() || Utility::isipv6(host) )
00345                 {
00346 #endif
00347                         in6_addr a;
00348                         if (!Utility::u2ip(host, a))
00349                         {
00350                                 SetCloseAndDelete();
00351                                 return false;
00352                         }
00353                         Ipv6Address ad(a, port);
00354                         Ipv6Address local;
00355                         return Open(ad, local);
00356 #ifdef ENABLE_RESOLVER
00357                 }
00358                 m_resolver_id = Resolve6(host, port);
00359                 return true;
00360 #endif
00361         }
00362 #endif
00363 #endif
00364 #ifdef ENABLE_RESOLVER
00365         if (!Handler().ResolverEnabled() || Utility::isipv4(host) )
00366         {
00367 #endif
00368                 ipaddr_t l;
00369                 if (!Utility::u2ip(host,l))
00370                 {
00371                         SetCloseAndDelete();
00372                         return false;
00373                 }
00374                 Ipv4Address ad(l, port);
00375                 Ipv4Address local;
00376                 return Open(ad, local);
00377 #ifdef ENABLE_RESOLVER
00378         }
00379         // resolve using async resolver thread
00380         m_resolver_id = Resolve(host, port);
00381         return true;
00382 #endif
00383 }

void TcpSocket::OnConnectTimeout (  )  [virtual]

Connect timeout callback.

Todo:
state reason why connect failed

Todo:
state reason why connect failed

Reimplemented from Socket.

Definition at line 1724 of file TcpSocket.cpp.

References StreamSocket::GetConnectionRetries(), StreamSocket::GetConnectionRetry(), Socket::Handler(), StreamSocket::IncreaseConnectionRetries(), LOG_LEVEL_FATAL, ISocketHandler::LogError(), Socket::OnConnectFailed(), Socket::OnConnectRetry(), OnSocks4ConnectFailed(), Socket::SetCloseAndDelete(), StreamSocket::SetConnecting(), Socket::SetRetryClientConnect(), and Socket::Socks4().

01725 {
01726         Handler().LogError(this, "connect", -1, "connect timeout", LOG_LEVEL_FATAL);
01727 #ifdef ENABLE_SOCKS4
01728         if (Socks4())
01729         {
01730                 OnSocks4ConnectFailed();
01731                 // retry direct connection
01732         }
01733         else
01734 #endif
01735         if (GetConnectionRetry() == -1 ||
01736                 (GetConnectionRetry() && GetConnectionRetries() < GetConnectionRetry()) )
01737         {
01738                 IncreaseConnectionRetries();
01739                 // ask socket via OnConnectRetry callback if we should continue trying
01740                 if (OnConnectRetry())
01741                 {
01742                         SetRetryClientConnect();
01743                 }
01744                 else
01745                 {
01746                         SetCloseAndDelete( true );
01748                         OnConnectFailed();
01749                         //
01750                         SetConnecting(false);
01751                 }
01752         }
01753         else
01754         {
01755                 SetCloseAndDelete(true);
01757                 OnConnectFailed();
01758                 //
01759                 SetConnecting(false);
01760         }
01761 }

int TcpSocket::Close (  )  [virtual]

Close file descriptor - internal use only.

See also:
SetCloseAndDelete

Reimplemented from Socket.

Definition at line 1400 of file TcpSocket.cpp.

References Socket::Close(), Errno, StreamSocket::GetShutdown(), Socket::GetSocket(), Socket::Handler(), INVALID_SOCKET, Socket::IsConnected(), Socket::IsSSL(), LOG_LEVEL_ERROR, LOG_LEVEL_WARNING, ISocketHandler::LogError(), Socket::Lost(), m_ssl, Socket::SetNonblocking(), and StrError.

01401 {
01402         if (GetSocket() == INVALID_SOCKET) // this could happen
01403         {
01404                 Handler().LogError(this, "Socket::Close", 0, "file descriptor invalid", LOG_LEVEL_WARNING);
01405                 return 0;
01406         }
01407         int n;
01408         SetNonblocking(true);
01409         if (!Lost() && IsConnected() && !(GetShutdown() & SHUT_WR))
01410         {
01411                 if (shutdown(GetSocket(), SHUT_WR) == -1)
01412                 {
01413                         // failed...
01414                         Handler().LogError(this, "shutdown", Errno, StrError(Errno), LOG_LEVEL_ERROR);
01415                 }
01416         }
01417         //
01418         char tmp[1000];
01419         if (!Lost() && (n = recv(GetSocket(),tmp,1000,0)) >= 0)
01420         {
01421                 if (n)
01422                 {
01423                         Handler().LogError(this, "read() after shutdown", n, "bytes read", LOG_LEVEL_WARNING);
01424                 }
01425         }
01426 #ifdef HAVE_OPENSSL
01427         if (IsSSL() && m_ssl)
01428                 SSL_shutdown(m_ssl);
01429         if (m_ssl)
01430         {
01431                 SSL_free(m_ssl);
01432                 m_ssl = NULL;
01433         }
01434 #endif
01435         return Socket::Close();
01436 }

void TcpSocket::Send ( const std::string &  s,
int  f = 0 
) [virtual]

void TcpSocket::Sendf ( const char *  format,
  ... 
)

Send string using printf formatting.

Definition at line 1083 of file TcpSocket.cpp.

References Send().

Referenced by HttpDebugSocket::OnFirst().

01084 {
01085         va_list ap;
01086         va_start(ap, format);
01087         char slask[5000]; // vsprintf / vsnprintf temporary
01088         vsnprintf(slask, sizeof(slask), format, ap);
01089         va_end(ap);
01090         Send( slask );
01091 }

void TcpSocket::SendBuf ( const char *  buf,
size_t  len,
int  f = 0 
) [virtual]

Send buffer of bytes.

Parameters:
buf Buffer pointer
len Length of data
f Dummy flags -- not used

Reimplemented from Socket.

Definition at line 894 of file TcpSocket.cpp.

References Buffer(), Socket::CloseAndDelete(), StreamSocket::Connecting(), Socket::GetSocket(), Socket::Handler(), INVALID_SOCKET, Socket::IsConnected(), Socket::IsDisableRead(), ISocketHandler::ISocketHandler_Mod(), Socket::IsSSL(), LOG_LEVEL_INFO, ISocketHandler::LogError(), m_obuf, m_obuf_top, StreamSocket::Ready(), SendFromOutputBuffer(), and TryWrite().

Referenced by HttpPostSocket::DoMultipartPost(), Ajp13Socket::IHttpServer_Respond(), HttpPutSocket::OnConnect(), HttpDebugSocket::OnData(), OnSocks4Connect(), HttpBaseSocket::OnTransferLimit(), Ajp13Socket::OnTransferLimit(), Ajp13Socket::ReceiveBody(), Ajp13Socket::ReceiveCPing(), Send(), and HttpdSocket::Send64().

00895 {
00896         if (!Ready() && !Connecting())
00897         {
00898                 Handler().LogError(this, "SendBuf", -1, "Attempt to write to a non-ready socket" ); // warning
00899                 if (GetSocket() == INVALID_SOCKET)
00900                         Handler().LogError(this, "SendBuf", 0, " * GetSocket() == INVALID_SOCKET", LOG_LEVEL_INFO);
00901                 if (Connecting())
00902                         Handler().LogError(this, "SendBuf", 0, " * Connecting()", LOG_LEVEL_INFO);
00903                 if (CloseAndDelete())
00904                         Handler().LogError(this, "SendBuf", 0, " * CloseAndDelete()", LOG_LEVEL_INFO);
00905                 return;
00906         }
00907         if (!IsConnected())
00908         {
00909                 Handler().LogError(this, "SendBuf", -1, "Attempt to write to a non-connected socket, will be sent on connect" ); // warning
00910                 Buffer(buf, len);
00911                 return;
00912         }
00913         if (m_obuf_top)
00914         {
00915                 Buffer(buf, len);
00916                 return;
00917         }
00918 #ifdef HAVE_OPENSSL
00919         if (IsSSL())
00920         {
00921                 Buffer(buf, len);
00922                 SendFromOutputBuffer();
00923                 return;
00924         }
00925 #endif
00926         int n = TryWrite(buf, len);
00927         if (n >= 0 && n < (int)len)
00928         {
00929                 Buffer(buf + n, len - n);
00930         }
00931         // if ( data in buffer || !IsConnected )
00932         // {
00933         //   add to buffer
00934         // }
00935         // else
00936         // try_send
00937         // if any data is unsent, buffer it and set m_wfds
00938 
00939         // check output buffer set, set/reset m_wfds accordingly
00940         {
00941                 bool br = !IsDisableRead();
00942                 if (m_obuf.size())
00943                         Handler().ISocketHandler_Mod(this, br, true);
00944                 else
00945                         Handler().ISocketHandler_Mod(this, br, false);
00946         }
00947 }

void TcpSocket::OnRawData ( const char *  buf,
size_t  len 
) [virtual]

This callback is executed after a successful read from the socket.

Parameters:
buf Pointer to the data
len Length of the data

Reimplemented in AjpBaseSocket, and HTTPSocket.

Definition at line 1464 of file TcpSocket.cpp.

Referenced by OnRead().

01465 {
01466 }

void TcpSocket::OnWriteComplete (  )  [virtual]

Called when output buffer has been sent.

Note: Will only be called IF the output buffer has been used. Send's that was successful without needing the output buffer will not generate a call to this method.

Definition at line 672 of file TcpSocket.cpp.

Referenced by SendFromOutputBuffer().

00673 {
00674 }

size_t TcpSocket::GetInputLength (  ) 

Number of bytes in input buffer.

Definition at line 1469 of file TcpSocket.cpp.

References TcpSocket::CircularBuffer::GetLength(), and ibuf.

Referenced by OnRead(), OnSocks4Read(), and ReadInput().

01470 {
01471         return ibuf.GetLength();
01472 }

size_t TcpSocket::ReadInput ( char *  buf,
size_t  sz 
)

Read from input buffer.

Definition at line 1475 of file TcpSocket.cpp.

References GetInputLength(), ibuf, and TcpSocket::CircularBuffer::Read().

01476 {
01477         size_t sz = max_sz < GetInputLength() ? max_sz : GetInputLength();
01478         ibuf.Read(buf, sz);
01479         return sz;
01480 }

size_t TcpSocket::GetOutputLength (  ) 

Number of bytes in output buffer.

Definition at line 1483 of file TcpSocket.cpp.

References m_output_length.

Referenced by HttpBaseSocket::OnTransferLimit(), Ajp13Socket::OnTransferLimit(), SendFromOutputBuffer(), and SSLNegotiate().

01484 {
01485         return m_output_length;
01486 }

void TcpSocket::OnLine ( const std::string &  line  )  [virtual]

Callback fires when a socket in line protocol has read one full line.

Parameters:
line Line read

Reimplemented from Socket.

Reimplemented in HTTPSocket, ResolvSocket, and SmtpdSocket.

Definition at line 950 of file TcpSocket.cpp.

Referenced by OnRead().

00951 {
00952 }

uint64_t TcpSocket::GetBytesReceived ( bool  clear = false  )  [virtual]

Get counter of number of bytes received.

Reimplemented from Socket.

Definition at line 1489 of file TcpSocket.cpp.

References m_bytes_received.

01490 {
01491         uint64_t z = m_bytes_received;
01492         if (clear)
01493                 m_bytes_received = 0;
01494         return z;
01495 }

uint64_t TcpSocket::GetBytesSent ( bool  clear = false  )  [virtual]

Get counter of number of bytes sent.

Reimplemented from Socket.

Definition at line 1498 of file TcpSocket.cpp.

References m_bytes_sent.

01499 {
01500         uint64_t z = m_bytes_sent;
01501         if (clear)
01502                 m_bytes_sent = 0;
01503         return z;
01504 }

void TcpSocket::OnSocks4Connect (  )  [virtual]

Socks4 specific callback.

Todo:
warn

Todo:
warn

Reimplemented from Socket.

Definition at line 969 of file TcpSocket.cpp.

References Socket::GetClientRemoteAddress(), Socket::GetSocks4Userid(), m_socks4_state, and SendBuf().

00970 {
00971         char request[1000];
00972         memset(request, 0, sizeof(request));
00973         request[0] = 4; // socks v4
00974         request[1] = 1; // command code: CONNECT
00975         {
00976                 std::auto_ptr<SocketAddress> ad = GetClientRemoteAddress();
00977                 if (ad.get())
00978                 {
00979                         struct sockaddr *p0 = (struct sockaddr *)*ad;
00980                         struct sockaddr_in *p = (struct sockaddr_in *)p0;
00981                         if (p -> sin_family == AF_INET)
00982                         {
00983                                 memcpy(request + 2, &p -> sin_port, 2); // nwbo is ok here
00984                                 memcpy(request + 4, &p -> sin_addr, sizeof(struct in_addr));
00985                         }
00986                         else
00987                         {
00989                         }
00990                 }
00991                 else
00992                 {
00994                 }
00995         }
00996 #if defined( _WIN32) && !defined(__CYGWIN__)
00997         strcpy_s(request + 8, sizeof(request) - 8, GetSocks4Userid().c_str());
00998 #else
00999         strcpy(request + 8, GetSocks4Userid().c_str());
01000 #endif
01001         size_t length = GetSocks4Userid().size() + 8 + 1;
01002         SendBuf(request, length);
01003         m_socks4_state = 0;
01004 }

void TcpSocket::OnSocks4ConnectFailed (  )  [virtual]

Socks4 specific callback.

Reimplemented from Socket.

Definition at line 1007 of file TcpSocket.cpp.

References Socket::Handler(), LOG_LEVEL_WARNING, ISocketHandler::LogError(), Socket::OnConnectFailed(), Socket::SetCloseAndDelete(), StreamSocket::SetConnecting(), and Socket::SetRetryClientConnect().

Referenced by OnConnectTimeout(), and OnWrite().

01008 {
01009         Handler().LogError(this,"OnSocks4ConnectFailed",0,"connection to socks4 server failed, trying direct connection",LOG_LEVEL_WARNING);
01010         if (!Handler().Socks4TryDirect())
01011         {
01012                 SetConnecting(false);
01013                 SetCloseAndDelete();
01014                 OnConnectFailed(); // just in case
01015         }
01016         else
01017         {
01018                 SetRetryClientConnect();
01019         }
01020 }

bool TcpSocket::OnSocks4Read (  )  [virtual]

Socks4 specific callback.

Returns:
'need_more'

Reimplemented from Socket.

Definition at line 1023 of file TcpSocket.cpp.

References GetInputLength(), Socket::Handler(), ibuf, LOG_LEVEL_FATAL, LOG_LEVEL_INFO, ISocketHandler::LogError(), m_socks4_cd, m_socks4_dstip, m_socks4_dstport, m_socks4_state, m_socks4_vn, Socket::OnConnect(), Socket::OnConnectFailed(), TcpSocket::CircularBuffer::Read(), Socket::SetCloseAndDelete(), StreamSocket::SetConnecting(), and Socket::SetSocks4().

Referenced by OnRead().

01024 {
01025         switch (m_socks4_state)
01026         {
01027         case 0:
01028                 ibuf.Read(&m_socks4_vn, 1);
01029                 m_socks4_state = 1;
01030                 break;
01031         case 1:
01032                 ibuf.Read(&m_socks4_cd, 1);
01033                 m_socks4_state = 2;
01034                 break;
01035         case 2:
01036                 if (GetInputLength() > 1)
01037                 {
01038                         ibuf.Read( (char *)&m_socks4_dstport, 2);
01039                         m_socks4_state = 3;
01040                 }
01041                 else
01042                 {
01043                         return true;
01044                 }
01045                 break;
01046         case 3:
01047                 if (GetInputLength() > 3)
01048                 {
01049                         ibuf.Read( (char *)&m_socks4_dstip, 4);
01050                         SetSocks4(false);
01051                         
01052                         switch (m_socks4_cd)
01053                         {
01054                         case 90:
01055                                 OnConnect();
01056                                 Handler().LogError(this, "OnSocks4Read", 0, "Connection established", LOG_LEVEL_INFO);
01057                                 break;
01058                         case 91:
01059                         case 92:
01060                         case 93:
01061                                 Handler().LogError(this,"OnSocks4Read",m_socks4_cd,"socks4 server reports connect failed",LOG_LEVEL_FATAL);
01062                                 SetConnecting(false);
01063                                 SetCloseAndDelete();
01064                                 OnConnectFailed();
01065                                 break;
01066                         default:
01067                                 Handler().LogError(this,"OnSocks4Read",m_socks4_cd,"socks4 server unrecognized response",LOG_LEVEL_FATAL);
01068                                 SetCloseAndDelete();
01069                                 break;
01070                         }
01071                 }
01072                 else
01073                 {
01074                         return true;
01075                 }
01076                 break;
01077         }
01078         return false;
01079 }

void TcpSocket::OnResolved ( int  id,
ipaddr_t  a,
port_t  port 
) [virtual]

Callback executed when resolver thread has finished a resolve request.

Reimplemented from Socket.

Definition at line 387 of file TcpSocket.cpp.

References ISocketHandler::Add(), DEB, Socket::Handler(), LOG_LEVEL_FATAL, ISocketHandler::LogError(), m_resolver_id, Open(), and Socket::SetCloseAndDelete().

Referenced by ResolvSocket::OnLine().

00388 {
00389 DEB(    fprintf(stderr, "TcpSocket::OnResolved id %d addr %x port %d\n", id, a, port);)
00390         if (id == m_resolver_id)
00391         {
00392                 if (a && port)
00393                 {
00394                         Ipv4Address ad(a, port);
00395                         Ipv4Address local;
00396                         if (Open(ad, local))
00397                         {
00398                                 if (!Handler().Valid(this))
00399                                 {
00400                                         Handler().Add(this);
00401                                 }
00402                         }
00403                 }
00404                 else
00405                 {
00406                         Handler().LogError(this, "OnResolved", 0, "Resolver failed", LOG_LEVEL_FATAL);
00407                         SetCloseAndDelete();
00408                 }
00409         }
00410         else
00411         {
00412                 Handler().LogError(this, "OnResolved", id, "Resolver returned wrong job id", LOG_LEVEL_FATAL);
00413                 SetCloseAndDelete();
00414         }
00415 }

void TcpSocket::OnSSLConnect (  )  [virtual]

Callback for 'New' ssl support - replaces SSLSocket.

Internal use.

Reimplemented from Socket.

Definition at line 1095 of file TcpSocket.cpp.

References DEB, Socket::GetSocket(), InitSSLClient(), m_sbio, m_ssl, m_ssl_ctx, Socket::SetCloseAndDelete(), Socket::SetNonblocking(), Socket::SetSSLNegotiate(), and SSLNegotiate().

01096 {
01097         SetNonblocking(true);
01098         {
01099                 if (m_ssl_ctx)
01100                 {
01101 DEB(                    fprintf(stderr, "SSL Context already initialized - closing socket\n");)
01102                         SetCloseAndDelete(true);
01103                         return;
01104                 }
01105                 InitSSLClient();
01106         }
01107         if (m_ssl_ctx)
01108         {
01109                 /* Connect the SSL socket */
01110                 m_ssl = SSL_new(m_ssl_ctx);
01111                 if (!m_ssl)
01112                 {
01113 DEB(                    fprintf(stderr, " m_ssl is NULL\n");)
01114                         SetCloseAndDelete(true);
01115                         return;
01116                 }
01117                 m_sbio = BIO_new_socket((int)GetSocket(), BIO_NOCLOSE);
01118                 if (!m_sbio)
01119                 {
01120 DEB(                    fprintf(stderr, " m_sbio is NULL\n");)
01121                         SetCloseAndDelete(true);
01122                         return;
01123                 }
01124                 SSL_set_bio(m_ssl, m_sbio, m_sbio);
01125                 if (!SSLNegotiate())
01126                 {
01127                         SetSSLNegotiate();
01128                 }
01129         }
01130         else
01131         {
01132                 SetCloseAndDelete();
01133         }
01134 }

void TcpSocket::OnSSLAccept (  )  [virtual]

Callback for 'New' ssl support - replaces SSLSocket.

Internal use.

Reimplemented from Socket.

Definition at line 1137 of file TcpSocket.cpp.

References DEB, Socket::GetSocket(), InitSSLServer(), m_sbio, m_ssl, m_ssl_ctx, Socket::SetCloseAndDelete(), Socket::SetNonblocking(), Socket::SetSSLNegotiate(), and Socket::SetSSLServer().

01138 {
01139         SetNonblocking(true);
01140         {
01141                 if (m_ssl_ctx)
01142                 {
01143 DEB(                    fprintf(stderr, "SSL Context already initialized - closing socket\n");)
01144                         SetCloseAndDelete(true);
01145                         return;
01146                 }
01147                 InitSSLServer();
01148                 SetSSLServer();
01149         }
01150         if (m_ssl_ctx)
01151         {
01152                 m_ssl = SSL_new(m_ssl_ctx);
01153                 if (!m_ssl)
01154                 {
01155 DEB(                    fprintf(stderr, " m_ssl is NULL\n");)
01156                         SetCloseAndDelete(true);
01157                         return;
01158                 }
01159                 m_sbio = BIO_new_socket((int)GetSocket(), BIO_NOCLOSE);
01160                 if (!m_sbio)
01161                 {
01162 DEB(                    fprintf(stderr, " m_sbio is NULL\n");)
01163                         SetCloseAndDelete(true);
01164                         return;
01165                 }
01166                 SSL_set_bio(m_ssl, m_sbio, m_sbio);
01167 //              if (!SSLNegotiate())
01168                 {
01169                         SetSSLNegotiate();
01170                 }
01171         }
01172 }

void TcpSocket::InitSSLClient (  )  [virtual]

This method must be implemented to initialize the ssl context for an outgoing connection.

Definition at line 1266 of file TcpSocket.cpp.

References InitializeContext().

Referenced by OnSSLConnect().

01267 {
01268         InitializeContext("", SSLv23_method());
01269 }

void TcpSocket::InitSSLServer (  )  [virtual]

This method must be implemented to initialize the ssl context for an incoming connection.

Definition at line 1272 of file TcpSocket.cpp.

References Socket::Handler(), LOG_LEVEL_FATAL, ISocketHandler::LogError(), and Socket::SetCloseAndDelete().

Referenced by OnSSLAccept().

01273 {
01274         Handler().LogError(this, "InitSSLServer", 0, "You MUST implement your own InitSSLServer method", LOG_LEVEL_FATAL);
01275         SetCloseAndDelete();
01276 }

void TcpSocket::SetReconnect ( bool  x = true  ) 

Flag that says a broken connection will try to reconnect.

Definition at line 1457 of file TcpSocket.cpp.

References m_b_reconnect.

01458 {
01459         m_b_reconnect = x;
01460 }

bool TcpSocket::Reconnect (  ) 

Check reconnect on lost connection flag status.

Definition at line 1508 of file TcpSocket.cpp.

References m_b_reconnect.

Referenced by Open().

01509 {
01510         return m_b_reconnect;
01511 }

void TcpSocket::SetIsReconnect ( bool  x = true  ) 

Flag to determine if a reconnect is in progress.

Definition at line 1514 of file TcpSocket.cpp.

References m_b_is_reconnect.

01515 {
01516         m_b_is_reconnect = x;
01517 }

bool TcpSocket::IsReconnect (  ) 

Socket is reconnecting.

Definition at line 1520 of file TcpSocket.cpp.

References m_b_is_reconnect.

Referenced by SSLNegotiate().

01521 {
01522         return m_b_is_reconnect;
01523 }

void TcpSocket::DisableInputBuffer ( bool  x = true  ) 

Use this if you only use OnRawData to process received data.

Definition at line 1535 of file TcpSocket.cpp.

References m_b_input_buffer_disabled.

Referenced by HTTPSocket::HTTPSocket(), and SetLineProtocol().

01536 {
01537         m_b_input_buffer_disabled = x;
01538 }

void TcpSocket::OnOptions ( int  family,
int  type,
int  protocol,
SOCKET  s 
) [virtual]

Called when a client socket is created, to set socket options.

Parameters:
family AF_INET, AF_INET6, etc
type SOCK_STREAM, SOCK_DGRAM, etc
protocol Protocol number (tcp, udp, sctp, etc)
s Socket file descriptor

Implements Socket.

Definition at line 1541 of file TcpSocket.cpp.

References DEB, Socket::SetSoKeepalive(), and Socket::SetSoReuseaddr().

01542 {
01543 DEB(    fprintf(stderr, "Socket::OnOptions()\n");)
01544 #ifdef SO_NOSIGPIPE
01545         SetSoNosigpipe(true);
01546 #endif
01547         SetSoReuseaddr(true);
01548         SetSoKeepalive(true);
01549 }

void TcpSocket::SetLineProtocol ( bool  x = true  )  [virtual]

Called after OnRead if socket is in line protocol mode.

See also:
SetLineProtocol Enable the OnLine callback. Do not create your own OnRead callback when using this.

Reimplemented from StreamSocket.

Definition at line 1552 of file TcpSocket.cpp.

References DisableInputBuffer(), and StreamSocket::SetLineProtocol().

Referenced by HTTPSocket::HTTPSocket(), HTTPSocket::OnLine(), HTTPSocket::OnRawData(), HTTPSocket::Reset(), ResolvSocket::ResolvSocket(), and SmtpdSocket::SmtpdSocket().

01553 {
01554         StreamSocket::SetLineProtocol(x);
01555         DisableInputBuffer(x);
01556 }

const std::string TcpSocket::GetLine (  )  const

Get the unfinished line when using SetLineProtocol = true.

The finished line will always be reported with a call to OnLine.

Definition at line 1559 of file TcpSocket.cpp.

References m_line, and m_line_ptr.

01560 {
01561         if (!m_line_ptr)
01562                 return "";
01563         return std::string(&m_line[0], m_line_ptr);
01564 }

bool TcpSocket::SetTcpNodelay ( bool  x = true  ) 

Definition at line 1567 of file TcpSocket.cpp.

References Errno, Socket::GetSocket(), Socket::Handler(), LOG_LEVEL_FATAL, LOG_LEVEL_INFO, ISocketHandler::LogError(), and StrError.

01568 {
01569 #ifdef TCP_NODELAY
01570         int optval = x ? 1 : 0;
01571         if (setsockopt(GetSocket(), IPPROTO_TCP, TCP_NODELAY, (char *)&optval, sizeof(optval)) == -1)
01572         {
01573                 Handler().LogError(this, "setsockopt(IPPROTO_TCP, TCP_NODELAY)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
01574                 return false;
01575         }
01576         return true;
01577 #else
01578         Handler().LogError(this, "socket option not available", 0, "TCP_NODELAY", LOG_LEVEL_INFO);
01579         return false;
01580 #endif
01581 }

int TcpSocket::Protocol (  )  [virtual]

Returns IPPROTO_TCP or IPPROTO_SCTP.

Implements StreamSocket.

Definition at line 1800 of file TcpSocket.cpp.

01801 {
01802         return IPPROTO_TCP;
01803 }

void TcpSocket::SetTransferLimit ( size_t  sz  ) 

Trigger limit for callback OnTransferLimit.

Definition at line 1806 of file TcpSocket.cpp.

References m_transfer_limit.

Referenced by HttpBaseSocket::OnTransferLimit(), and Ajp13Socket::OnTransferLimit().

01807 {
01808         m_transfer_limit = sz;
01809 }

void TcpSocket::OnTransferLimit (  )  [virtual]

This callback fires when the output buffer drops below the value set by SetTransferLimit.

Default: 0 (disabled).

Reimplemented in Ajp13Socket, and HttpBaseSocket.

Definition at line 1812 of file TcpSocket.cpp.

Referenced by SendFromOutputBuffer().

01813 {
01814 }

void TcpSocket::OnRead (  )  [protected, virtual]

Called when there is something to be read from the file descriptor.

Reimplemented from Socket.

Definition at line 446 of file TcpSocket.cpp.

References DEB, Errno, Socket::GetSocket(), Socket::GetTrafficMonitor(), Socket::Handler(), ibuf, Socket::IsSSL(), LOG_LEVEL_ERROR, LOG_LEVEL_FATAL, LOG_LEVEL_WARNING, ISocketHandler::LogError(), m_b_input_buffer_disabled, m_buf, m_bytes_received, m_ssl, Socket::OnDisconnect(), StreamSocket::Ready(), Socket::SetCloseAndDelete(), StreamSocket::SetFlushBeforeClose(), Socket::SetLost(), StreamSocket::SetShutdown(), StrError, TCP_BUFSIZE_READ, TCP_DISCONNECT_ERROR, TCP_DISCONNECT_SSL, and TcpSocket::CircularBuffer::Write().

Referenced by HTTPSocket::OnRawData().

00447 {
00448         int n = 0;
00449 #ifdef SOCKETS_DYNAMIC_TEMP
00450         char *buf = m_buf;
00451 #else
00452         char buf[TCP_BUFSIZE_READ];
00453 #endif
00454 #ifdef HAVE_OPENSSL
00455         if (IsSSL())
00456         {
00457                 if (!Ready())
00458                         return;
00459                 n = SSL_read(m_ssl, buf, TCP_BUFSIZE_READ);
00460                 if (n == -1)
00461                 {
00462                         n = SSL_get_error(m_ssl, n);
00463                         switch (n)
00464                         {
00465                         case SSL_ERROR_NONE:
00466                         case SSL_ERROR_WANT_READ:
00467                         case SSL_ERROR_WANT_WRITE:
00468                                 break;
00469                         case SSL_ERROR_ZERO_RETURN:
00470 DEB(                            fprintf(stderr, "SSL_read() returns zero - closing socket\n");)
00471                                 OnDisconnect();
00472                                 OnDisconnect(TCP_DISCONNECT_SSL|TCP_DISCONNECT_ERROR, n);
00473                                 SetCloseAndDelete(true);
00474                                 SetFlushBeforeClose(false);
00475                                 SetLost();
00476                                 break;
00477                         default:
00478 DEB(                            fprintf(stderr, "SSL read problem, errcode = %d\n",n);)
00479                                 OnDisconnect();
00480                                 OnDisconnect(TCP_DISCONNECT_SSL|TCP_DISCONNECT_ERROR, n);
00481                                 SetCloseAndDelete(true);
00482                                 SetFlushBeforeClose(false);
00483                                 SetLost();
00484                         }
00485                         return;
00486                 }
00487                 else
00488                 if (!n)
00489                 {
00490 DEB(                    n = SSL_get_error(m_ssl, n);
00491                         fprintf(stderr, "SSL_read returns 0, SSL_get_error: %d\n", n);
00492                         if (n == SSL_ERROR_SYSCALL)
00493                         {
00494                                 fprintf(stderr, "ERR_get_error() returns %ld\n", ERR_get_error());
00495                                 perror("errno: SSL_read");
00496                         })
00497                         OnDisconnect();
00498                         OnDisconnect(TCP_DISCONNECT_SSL, 0);
00499                         SetCloseAndDelete(true);
00500                         SetFlushBeforeClose(false);
00501                         SetLost();
00502                         SetShutdown(SHUT_WR);
00503                         return;
00504                 }
00505                 else
00506                 if (n > 0 && n <= TCP_BUFSIZE_READ)
00507                 {
00508                         m_bytes_received += n;
00509                         if (GetTrafficMonitor())
00510                         {
00511                                 GetTrafficMonitor() -> fwrite(buf, 1, n);
00512                         }
00513                         if (!m_b_input_buffer_disabled && !ibuf.Write(buf,n))
00514                         {
00515                                 Handler().LogError(this, "OnRead(ssl)", 0, "ibuf overflow", LOG_LEVEL_WARNING);
00516                         }
00517                 }
00518                 else
00519                 {
00520                         Handler().LogError(this, "OnRead(ssl)", n, "abnormal value from SSL_read", LOG_LEVEL_ERROR);
00521                 }
00522         }
00523         else
00524 #endif // HAVE_OPENSSL
00525         {
00526                 n = recv(GetSocket(), buf, TCP_BUFSIZE_READ, MSG_NOSIGNAL);
00527                 if (n == -1)
00528                 {
00529                         Handler().LogError(this, "read", Errno, StrError(Errno), LOG_LEVEL_FATAL);
00530                         OnDisconnect();
00531                         OnDisconnect(TCP_DISCONNECT_ERROR, Errno);
00532                         SetCloseAndDelete(true);
00533                         SetFlushBeforeClose(false);
00534                         SetLost();
00535                         return;
00536                 }
00537                 else
00538                 if (!n)
00539                 {
00540                         OnDisconnect();
00541                         OnDisconnect(0, 0);
00542                         SetCloseAndDelete(true);
00543                         SetFlushBeforeClose(false);
00544                         SetLost();
00545                         SetShutdown(SHUT_WR);
00546                         return;
00547                 }
00548                 else
00549                 if (n > 0 && n <= TCP_BUFSIZE_READ)
00550                 {
00551                         m_bytes_received += n;
00552                         if (GetTrafficMonitor())
00553                         {
00554                                 GetTrafficMonitor() -> fwrite(buf, 1, n);
00555                         }
00556                         if (!m_b_input_buffer_disabled && !ibuf.Write(buf,n))
00557                         {
00558                                 Handler().LogError(this, "OnRead", 0, "ibuf overflow", LOG_LEVEL_WARNING);
00559                         }
00560                 }
00561                 else
00562                 {
00563                         Handler().LogError(this, "OnRead", n, "abnormal value from recv", LOG_LEVEL_ERROR);
00564                 }
00565         }
00566         //
00567         OnRead( buf, n );
00568 }

void TcpSocket::OnRead ( char *  buf,
size_t  n 
) [protected]

Definition at line 571 of file TcpSocket.cpp.

References Socket::CloseAndDelete(), GetInputLength(), Socket::Handler(), StreamSocket::LineProtocol(), LOG_LEVEL_FATAL, ISocketHandler::LogError(), m_b_input_buffer_disabled, m_c, m_line, m_line_ptr, m_skip_c, OnLine(), OnRawData(), OnSocks4Read(), Socket::SetCloseAndDelete(), Socket::Socks4(), and TCP_BUFSIZE_READ.

00572 {
00573         // unbuffered
00574         if (n > 0 && n <= TCP_BUFSIZE_READ)
00575         {
00576                 if (LineProtocol())
00577                 {
00578                         buf[n] = 0;
00579                         size_t i = 0;
00580                         if (m_skip_c && (buf[i] == 13 || buf[i] == 10) && buf[i] != m_c)
00581                         {
00582                                 m_skip_c = false;
00583                                 i++;
00584                         }
00585                         size_t x = i;
00586                         for (; i < n && LineProtocol(); i++)
00587                         {
00588                                 while ((buf[i] == 13 || buf[i] == 10) && LineProtocol())
00589                                 {
00590                                         char c = buf[i];
00591                                         buf[i] = 0;
00592                                         if (buf[x])
00593                                         {
00594                                                 size_t sz = strlen(&buf[x]);
00595                                                 if (m_line_ptr + sz < Handler().MaxTcpLineSize())
00596                                                 {
00597                                                         memcpy(&m_line[m_line_ptr], &buf[x], sz);
00598                                                         m_line_ptr += sz;
00599                                                 }
00600                                                 else
00601                                                 {
00602                                                         Handler().LogError(this, "TcpSocket::OnRead", (int)(m_line_ptr + sz), "maximum tcp_line_size exceeded, connection closed", LOG_LEVEL_FATAL);
00603                                                         SetCloseAndDelete();
00604                                                 }
00605                                         }
00606                                         if (m_line_ptr > 0)
00607                                                 OnLine( std::string(&m_line[0], m_line_ptr) );
00608                                         else
00609                                                 OnLine( "" );
00610                                         i++;
00611                                         m_skip_c = true;
00612                                         m_c = c;
00613                                         if (i < n && (buf[i] == 13 || buf[i] == 10) && buf[i] != c)
00614                                         {
00615                                                 m_skip_c = false;
00616                                                 i++;
00617                                         }
00618                                         x = i;
00619                                         m_line_ptr = 0;
00620                                 }
00621                                 if (!LineProtocol())
00622                                 {
00623                                         break;
00624                                 }
00625                         }
00626                         if (!LineProtocol())
00627                         {
00628                                 if (i < n)
00629                                 {
00630                                         OnRawData(buf + i, n - i);
00631                                 }
00632                         }
00633                         else
00634                         if (buf[x])
00635                         {
00636                                 size_t sz = strlen(&buf[x]);
00637                                 if (m_line_ptr + sz < Handler().MaxTcpLineSize())
00638                                 {
00639                                         memcpy(&m_line[m_line_ptr], &buf[x], sz);
00640                                         m_line_ptr += sz;
00641                                 }
00642                                 else
00643                                 {
00644                                         Handler().LogError(this, "TcpSocket::OnRead", (int)(m_line_ptr + sz), "maximum tcp_line_size exceeded, connection closed", LOG_LEVEL_FATAL);
00645                                         SetCloseAndDelete();
00646                                 }
00647                         }
00648                 }
00649                 else
00650                 {
00651                         OnRawData(buf, n);
00652                 }
00653         }
00654         if (m_b_input_buffer_disabled)
00655         {
00656                 return;
00657         }
00658         // further processing: socks4
00659 #ifdef ENABLE_SOCKS4
00660         if (Socks4())
00661         {
00662                 bool need_more = false;
00663                 while (GetInputLength() && !need_more && !CloseAndDelete())
00664                 {
00665                         need_more = OnSocks4Read();
00666                 }
00667         }
00668 #endif
00669 }

void TcpSocket::OnWrite (  )  [protected, virtual]

Called when there is room for another write on the file descriptor.

Reimplemented from Socket.

Definition at line 677 of file TcpSocket.cpp.

References StreamSocket::Connecting(), StreamSocket::GetConnectionRetries(), StreamSocket::GetConnectionRetry(), Socket::Handler(), Socket::IsDisableRead(), ISocketHandler::ISocketHandler_Mod(), LOG_LEVEL_FATAL, ISocketHandler::LogError(), Socket::OnConnectFailed(), OnSocks4ConnectFailed(), SendFromOutputBuffer(), Socket::SetCallOnConnect(), Socket::SetCloseAndDelete(), StreamSocket::SetConnecting(), Socket::Socks4(), Socket::SoError(), and StrError.

Referenced by SSLNegotiate().

00678 {
00679         if (Connecting())
00680         {
00681                 int err = SoError();
00682 
00683                 // don't reset connecting flag on error here, we want the OnConnectFailed timeout later on
00684                 if (!err) // ok
00685                 {
00686                         Handler().ISocketHandler_Mod(this, !IsDisableRead(), false);
00687                         SetConnecting(false);
00688                         SetCallOnConnect();
00689                         return;
00690                 }
00691                 Handler().LogError(this, "tcp: connect failed", err, StrError(err), LOG_LEVEL_FATAL);
00692                 Handler().ISocketHandler_Mod(this, false, false); // no more monitoring because connection failed
00693 
00694                 // failed
00695 #ifdef ENABLE_SOCKS4
00696                 if (Socks4())
00697                 {
00698                         // %! leave 'Connecting' flag set?
00699                         OnSocks4ConnectFailed();
00700                         return;
00701                 }
00702 #endif
00703                 if (GetConnectionRetry() == -1 ||
00704                         (GetConnectionRetry() && GetConnectionRetries() < GetConnectionRetry()) )
00705                 {
00706                         // even though the connection failed at once, only retry after
00707                         // the connection timeout.
00708                         // should we even try to connect again, when CheckConnect returns
00709                         // false it's because of a connection error - not a timeout...
00710                         return;
00711                 }
00712                 SetConnecting(false);
00713                 SetCloseAndDelete( true );
00715                 OnConnectFailed();
00716                 return;
00717         }
00718 
00719         SendFromOutputBuffer();
00720 }

void TcpSocket::InitializeContext ( const std::string &  context,
const SSL_METHOD *  meth_in = NULL 
) [protected]

SSL; Initialize ssl context for a client socket.

Parameters:
meth_in SSL method

Definition at line 1279 of file TcpSocket.cpp.

References m_client_contexts, and m_ssl_ctx.

Referenced by InitializeContext(), and InitSSLClient().

01280 {
01281         static Mutex mutex;
01282         Lock lock(mutex);
01283         /* Create our context*/
01284         if (m_client_contexts.find(context) == m_client_contexts.end())
01285         {
01286                 const SSL_METHOD *meth = meth_in ? meth_in : SSLv3_method();
01287                 m_ssl_ctx = m_client_contexts[context] = SSL_CTX_new(const_cast<SSL_METHOD *>(meth));
01288                 SSL_CTX_set_mode(m_ssl_ctx, SSL_MODE_AUTO_RETRY|SSL_MODE_ENABLE_PARTIAL_WRITE);
01289         }
01290         else
01291         {
01292                 m_ssl_ctx = m_client_contexts[context];
01293         }
01294 }

void TcpSocket::InitializeContext ( const std::string &  context,
const std::string &  keyfile,
const std::string &  password,
const SSL_METHOD *  meth_in = NULL 
) [protected]

SSL; Initialize ssl context for a server socket.

Parameters:
keyfile Combined private key/certificate file
password Password for private key
meth_in SSL method

Definition at line 1297 of file TcpSocket.cpp.

References InitializeContext().

01298 {
01299         InitializeContext(context, keyfile, keyfile, password, meth_in);
01300 /*
01301         Lock lock(m_server_ssl_mutex);
01302         // Create our context
01303         if (m_server_contexts.find(context) == m_server_contexts.end())
01304         {
01305                 const SSL_METHOD *meth = meth_in ? meth_in : SSLv3_method();
01306                 m_ssl_ctx = m_server_contexts[context] = SSL_CTX_new(const_cast<SSL_METHOD *>(meth));
01307                 SSL_CTX_set_mode(m_ssl_ctx, SSL_MODE_AUTO_RETRY|SSL_MODE_ENABLE_PARTIAL_WRITE);
01308                 // session id
01309                 if (context.size())
01310                         SSL_CTX_set_session_id_context(m_ssl_ctx, (const unsigned char *)context.c_str(), (unsigned int)context.size());
01311                 else
01312                         SSL_CTX_set_session_id_context(m_ssl_ctx, (const unsigned char *)"--empty--", 9);
01313         }
01314         else
01315         {
01316                 m_ssl_ctx = m_server_contexts[context];
01317         }
01318 
01319         // Load our keys and certificates
01320         if (!(SSL_CTX_use_certificate_file(m_ssl_ctx, keyfile.c_str(), SSL_FILETYPE_PEM)))
01321         {
01322                 Handler().LogError(this, "TcpSocket InitializeContext", 0, "Couldn't read certificate file " + keyfile, LOG_LEVEL_FATAL);
01323         }
01324 
01325         m_password = password;
01326         SSL_CTX_set_default_passwd_cb(m_ssl_ctx, SSL_password_cb);
01327         SSL_CTX_set_default_passwd_cb_userdata(m_ssl_ctx, this);
01328         if (!(SSL_CTX_use_PrivateKey_file(m_ssl_ctx, keyfile.c_str(), SSL_FILETYPE_PEM)))
01329         {
01330                 Handler().LogError(this, "TcpSocket InitializeContext", 0, "Couldn't read private key file " + keyfile, LOG_LEVEL_FATAL);
01331         }
01332 */
01333 }

void TcpSocket::InitializeContext ( const std::string &  context,
const std::string &  certfile,
const std::string &  keyfile,
const std::string &  password,
const SSL_METHOD *  meth_in = NULL 
) [protected]

SSL; Initialize ssl context for a server socket.

Parameters:
certfile Separate certificate file
keyfile Combined private key/certificate file
password Password for private key
meth_in SSL method

Definition at line 1336 of file TcpSocket.cpp.

References Socket::Handler(), LOG_LEVEL_FATAL, ISocketHandler::LogError(), m_password, m_server_contexts, m_server_ssl_mutex, m_ssl_ctx, and SSL_password_cb().

01337 {
01338         Lock lock(m_server_ssl_mutex);
01339         /* Create our context*/
01340         if (m_server_contexts.find(context) == m_server_contexts.end())
01341         {
01342                 const SSL_METHOD *meth = meth_in ? meth_in : SSLv3_method();
01343                 m_ssl_ctx = m_server_contexts[context] = SSL_CTX_new(const_cast<SSL_METHOD *>(meth));
01344                 SSL_CTX_set_mode(m_ssl_ctx, SSL_MODE_AUTO_RETRY|SSL_MODE_ENABLE_PARTIAL_WRITE);
01345                 // session id
01346                 if (context.size())
01347                         SSL_CTX_set_session_id_context(m_ssl_ctx, (const unsigned char *)context.c_str(), (unsigned int)context.size());
01348                 else
01349                         SSL_CTX_set_session_id_context(m_ssl_ctx, (const unsigned char *)"--empty--", 9);
01350         }
01351         else
01352         {
01353                 m_ssl_ctx = m_server_contexts[context];
01354         }
01355 
01356         /* Load our keys and certificates*/
01357         if (!(SSL_CTX_use_certificate_file(m_ssl_ctx, certfile.c_str(), SSL_FILETYPE_PEM)))
01358         {
01359                 Handler().LogError(this, "TcpSocket InitializeContext", 0, "Couldn't read certificate file " + keyfile, LOG_LEVEL_FATAL);
01360         }
01361 
01362         m_password = password;
01363         SSL_CTX_set_default_passwd_cb(m_ssl_ctx, SSL_password_cb);
01364         SSL_CTX_set_default_passwd_cb_userdata(m_ssl_ctx, this);
01365         if (!(SSL_CTX_use_PrivateKey_file(m_ssl_ctx, keyfile.c_str(), SSL_FILETYPE_PEM)))
01366         {
01367                 Handler().LogError(this, "TcpSocket InitializeContext", 0, "Couldn't read private key file " + keyfile, LOG_LEVEL_FATAL);
01368         }
01369 }

void TcpSocket::UseCertificateChainFile ( const std::string &  filename  )  [protected]

SSL; load certificate chain from file.

Definition at line 1372 of file TcpSocket.cpp.

References Socket::Handler(), LOG_LEVEL_ERROR, ISocketHandler::LogError(), and m_ssl_ctx.

01373 {
01374         if (!(SSL_CTX_use_certificate_chain_file(m_ssl_ctx, filename.c_str())))
01375         {
01376                 Handler().LogError(this, "TcpSocket UseCertificateChainFile", 0, "Couldn't read certificate file " + filename, LOG_LEVEL_ERROR);
01377         }
01378 }

int TcpSocket::SSL_password_cb ( char *  buf,
int  num,
int  rwflag,
void *  userdata 
) [static, protected]

SSL; Password callback method.

Definition at line 1381 of file TcpSocket.cpp.

References GetPassword().

Referenced by InitializeContext().

01382 {
01383         Socket *p0 = static_cast<Socket *>(userdata);
01384         TcpSocket *p = dynamic_cast<TcpSocket *>(p0);
01385         std::string pw = p ? p -> GetPassword() : "";
01386         if ( (size_t)num < pw.size() + 1)
01387         {
01388                 return 0;
01389         }
01390 #if defined( _WIN32) && !defined(__CYGWIN__)
01391         strcpy_s(buf, num, pw.c_str());
01392 #else
01393         strcpy(buf,pw.c_str());
01394 #endif
01395         return (int)pw.size();
01396 }

SSL_CTX * TcpSocket::GetSslContext (  )  [protected, virtual]

SSL; Get pointer to ssl context structure.

Reimplemented from Socket.

Definition at line 1440 of file TcpSocket.cpp.

References Socket::Handler(), LOG_LEVEL_WARNING, ISocketHandler::LogError(), and m_ssl_ctx.

01441 {
01442         if (!m_ssl_ctx)
01443                 Handler().LogError(this, "GetSslContext", 0, "SSL Context is NULL; check InitSSLServer/InitSSLClient", LOG_LEVEL_WARNING);
01444         return m_ssl_ctx;
01445 }

SSL * TcpSocket::GetSsl (  )  [protected, virtual]

SSL; Get pointer to ssl structure.

Reimplemented from Socket.

Definition at line 1447 of file TcpSocket.cpp.

References Socket::Handler(), LOG_LEVEL_WARNING, ISocketHandler::LogError(), and m_ssl.

01448 {
01449         if (!m_ssl)
01450                 Handler().LogError(this, "GetSsl", 0, "SSL is NULL; check InitSSLServer/InitSSLClient", LOG_LEVEL_WARNING);
01451         return m_ssl;
01452 }

bool TcpSocket::SSLNegotiate (  )  [protected, virtual]

ssl; still negotiating connection.

Todo:
: resurrect certificate check... client

Todo:
: resurrect certificate check... server

Reimplemented from Socket.

Definition at line 1175 of file TcpSocket.cpp.

References DEB, GetOutputLength(), Socket::Handler(), IsReconnect(), Socket::IsSSLServer(), LOG_LEVEL_INFO, ISocketHandler::LogError(), m_ssl, Socket::OnAccept(), Socket::OnConnect(), Socket::OnReconnect(), Socket::OnSSLAcceptFailed(), Socket::OnSSLConnectFailed(), OnWrite(), Socket::SetCloseAndDelete(), Socket::SetConnected(), and Socket::SetSSLNegotiate().

Referenced by OnSSLConnect().

01176 {
01177         if (!IsSSLServer()) // client
01178         {
01179                 int r = SSL_connect(m_ssl);
01180                 if (r > 0)
01181                 {
01182                         SetSSLNegotiate(false);
01184 //                      CheckCertificateChain( "");//ServerHOST);
01185                         SetConnected();
01186                         if (GetOutputLength())
01187                         {
01188                                 OnWrite();
01189                         }
01190 #ifdef ENABLE_RECONNECT
01191                         if (IsReconnect())
01192                         {
01193                                 OnReconnect();
01194                         }
01195                         else
01196 #endif
01197                         {
01198                                 OnConnect();
01199                         }
01200                         Handler().LogError(this, "SSLNegotiate/SSL_connect", 0, "Connection established", LOG_LEVEL_INFO);
01201                         return true;
01202                 }
01203                 else
01204                 if (!r)
01205                 {
01206                         Handler().LogError(this, "SSLNegotiate/SSL_connect", 0, "Connection failed", LOG_LEVEL_INFO);
01207                         SetSSLNegotiate(false);
01208                         SetCloseAndDelete();
01209                         OnSSLConnectFailed();
01210                 }
01211                 else
01212                 {
01213                         r = SSL_get_error(m_ssl, r);
01214                         if (r != SSL_ERROR_WANT_READ && r != SSL_ERROR_WANT_WRITE)
01215                         {
01216                                 Handler().LogError(this, "SSLNegotiate/SSL_connect", -1, "Connection failed", LOG_LEVEL_INFO);
01217 DEB(                            fprintf(stderr, "SSL_connect() failed - closing socket, return code: %d\n",r);)
01218                                 SetSSLNegotiate(false);
01219                                 SetCloseAndDelete(true);
01220                                 OnSSLConnectFailed();
01221                         }
01222                 }
01223         }
01224         else // server
01225         {
01226                 int r = SSL_accept(m_ssl);
01227                 if (r > 0)
01228                 {
01229                         SetSSLNegotiate(false);
01231 //                      CheckCertificateChain( "");//ClientHOST);
01232                         SetConnected();
01233                         if (GetOutputLength())
01234                         {
01235                                 OnWrite();
01236                         }
01237                         OnAccept();
01238                         Handler().LogError(this, "SSLNegotiate/SSL_accept", 0, "Connection established", LOG_LEVEL_INFO);
01239                         return true;
01240                 }
01241                 else
01242                 if (!r)
01243                 {
01244                         Handler().LogError(this, "SSLNegotiate/SSL_accept", 0, "Connection failed", LOG_LEVEL_INFO);
01245                         SetSSLNegotiate(false);
01246                         SetCloseAndDelete();
01247                         OnSSLAcceptFailed();
01248                 }
01249                 else
01250                 {
01251                         r = SSL_get_error(m_ssl, r);
01252                         if (r != SSL_ERROR_WANT_READ && r != SSL_ERROR_WANT_WRITE)
01253                         {
01254                                 Handler().LogError(this, "SSLNegotiate/SSL_accept", -1, "Connection failed", LOG_LEVEL_INFO);
01255 DEB(                            fprintf(stderr, "SSL_accept() failed - closing socket, return code: %d\n",r);)
01256                                 SetSSLNegotiate(false);
01257                                 SetCloseAndDelete(true);
01258                                 OnSSLAcceptFailed();
01259                         }
01260                 }
01261         }
01262         return false;
01263 }

const std::string & TcpSocket::GetPassword (  )  [protected]

SSL; Get ssl password.

Definition at line 1528 of file TcpSocket.cpp.

References m_password.

Referenced by SSL_password_cb().

01529 {
01530         return m_password;
01531 }

TcpSocket& TcpSocket::operator= ( const TcpSocket  )  [inline, private]

Definition at line 305 of file TcpSocket.h.

00305 { return *this; }

void TcpSocket::SendFromOutputBuffer (  )  [private]

Definition at line 723 of file TcpSocket.cpp.

References GetOutputLength(), Socket::Handler(), Socket::IsDisableRead(), ISocketHandler::ISocketHandler_Mod(), LOG_LEVEL_ERROR, ISocketHandler::LogError(), m_obuf, m_obuf_top, m_output_length, m_transfer_limit, OnTransferLimit(), OnWriteComplete(), and TryWrite().

Referenced by OnWrite(), and SendBuf().

00724 {
00725         // try send next block in buffer
00726         // if full block is sent, repeat
00727         // if all blocks are sent, reset m_wfds
00728 
00729         bool repeat = false;
00730         size_t sz = m_transfer_limit ? GetOutputLength() : 0;
00731         do
00732         {
00733                 if (m_obuf.empty())
00734                 {
00735                         Handler().LogError(this, "OnWrite", (int)m_output_length, "Empty output buffer in OnWrite", LOG_LEVEL_ERROR);
00736                         break;
00737                 }
00738                 output_l::iterator it = m_obuf.begin();
00739                 OUTPUT *p = *it;
00740                 repeat = false;
00741                 int n = TryWrite(p -> Buf(), p -> Len());
00742                 if (n > 0)
00743                 {
00744                         size_t left = p -> Remove(n);
00745                         m_output_length -= n;
00746                         if (!left)
00747                         {
00748                                 delete p;
00749                                 m_obuf.erase(it);
00750                                 if (!m_obuf.size())
00751                                 {
00752                                         m_obuf_top = NULL;
00753                                         OnWriteComplete();
00754                                 }
00755                                 else
00756                                 {
00757                                         repeat = true;
00758                                 }
00759                         }
00760                 }
00761         } while (repeat);
00762 
00763         if (m_transfer_limit && sz > m_transfer_limit && GetOutputLength() < m_transfer_limit)
00764         {
00765                 OnTransferLimit();
00766         }
00767 
00768         // check output buffer set, set/reset m_wfds accordingly
00769         {
00770                 bool br = !IsDisableRead();
00771                 if (m_obuf.size())
00772                         Handler().ISocketHandler_Mod(this, br, true);
00773                 else
00774                         Handler().ISocketHandler_Mod(this, br, false);
00775         }
00776 }

int TcpSocket::TryWrite ( const char *  buf,
size_t  len 
) [private]

the actual send()

Definition at line 779 of file TcpSocket.cpp.

References Errno, Socket::GetSocket(), Socket::GetTrafficMonitor(), Socket::Handler(), Socket::IsSSL(), LOG_LEVEL_FATAL, ISocketHandler::LogError(), m_bytes_sent, m_repeat_length, m_ssl, Socket::OnDisconnect(), Socket::SetCloseAndDelete(), StreamSocket::SetFlushBeforeClose(), Socket::SetLost(), StrError, TCP_DISCONNECT_ERROR, TCP_DISCONNECT_SSL, and TCP_DISCONNECT_WRITE.

Referenced by SendBuf(), and SendFromOutputBuffer().

00780 {
00781         int n = 0;
00782 #ifdef HAVE_OPENSSL
00783         if (IsSSL())
00784         {
00785                 n = SSL_write(m_ssl, buf, (int)(m_repeat_length ? m_repeat_length : len));
00786                 if (n == -1)
00787                 {
00788                         int errnr = SSL_get_error(m_ssl, n);
00789                         if ( errnr == SSL_ERROR_WANT_READ || errnr == SSL_ERROR_WANT_WRITE )
00790                         {
00791                                 m_repeat_length = m_repeat_length ? m_repeat_length : len;
00792                         }
00793                         else
00794                         {
00795                                 OnDisconnect();
00796                                 OnDisconnect(TCP_DISCONNECT_WRITE|TCP_DISCONNECT_ERROR|TCP_DISCONNECT_SSL, errnr);
00797                                 SetCloseAndDelete(true);
00798                                 SetFlushBeforeClose(false);
00799                                 SetLost();
00800                                 {
00801                                         char errbuf[256];
00802                                         ERR_error_string_n(errnr, errbuf, 256);
00803                                         Handler().LogError(this, "OnWrite/SSL_write", errnr, errbuf, LOG_LEVEL_FATAL);
00804                                 }
00805                         }
00806                         return 0;
00807                 }
00808                 else
00809                 if (!n)
00810                 {
00811                         OnDisconnect();
00812                         OnDisconnect(TCP_DISCONNECT_WRITE|TCP_DISCONNECT_SSL, 0);
00813                         SetCloseAndDelete(true);
00814                         SetFlushBeforeClose(false);
00815                         SetLost();
00816                 }
00817                 m_repeat_length = 0;
00818         }
00819         else
00820 #endif // HAVE_OPENSSL
00821         {
00822                 n = send(GetSocket(), buf, (int)len, MSG_NOSIGNAL);
00823                 if (n == -1)
00824                 {
00825                 // normal error codes:
00826                 // WSAEWOULDBLOCK
00827                 //       EAGAIN or EWOULDBLOCK
00828 #ifdef _WIN32
00829                         if (Errno != WSAEWOULDBLOCK)
00830 #else
00831                         if (Errno != EWOULDBLOCK)
00832 #endif
00833                         {       
00834                                 Handler().LogError(this, "send", Errno, StrError(Errno), LOG_LEVEL_FATAL);
00835                                 OnDisconnect();
00836                                 OnDisconnect(TCP_DISCONNECT_WRITE|TCP_DISCONNECT_ERROR, Errno);
00837                                 SetCloseAndDelete(true);
00838                                 SetFlushBeforeClose(false);
00839                                 SetLost();
00840                         }
00841                         return 0;
00842                 }
00843         }
00844         if (n > 0)
00845         {
00846                 m_bytes_sent += n;
00847                 if (GetTrafficMonitor())
00848                 {
00849                         GetTrafficMonitor() -> fwrite(buf, 1, n);
00850                 }
00851         }
00852         return n;
00853 }

void TcpSocket::Buffer ( const char *  buf,
size_t  len 
) [private]

add data to output buffer top

Definition at line 856 of file TcpSocket.cpp.

References m_obuf, m_obuf_top, and m_output_length.

Referenced by SendBuf().

00857 {
00858         size_t ptr = 0;
00859         m_output_length += len;
00860         while (ptr < len)
00861         {
00862                 // buf/len => pbuf/sz
00863                 size_t space = 0;
00864                 if ((space = m_obuf_top ? m_obuf_top -> Space() : 0) > 0)
00865                 {
00866                         const char *pbuf = buf + ptr;
00867                         size_t sz = len - ptr;
00868                         if (space >= sz)
00869                         {
00870                                 m_obuf_top -> Add(pbuf, sz);
00871                                 ptr += sz;
00872                         }
00873                         else
00874                         {
00875                                 m_obuf_top -> Add(pbuf, space);
00876                                 ptr += space;
00877                         }
00878                 }
00879                 else
00880                 {
00881                         m_obuf_top = new OUTPUT;
00882                         m_obuf.push_back( m_obuf_top );
00883                 }
00884         }
00885 }


Member Data Documentation

Circular input buffer.

Definition at line 302 of file TcpSocket.h.

Referenced by GetInputLength(), OnRead(), OnSocks4Read(), and ReadInput().

Definition at line 315 of file TcpSocket.h.

Referenced by DisableInputBuffer(), and OnRead().

uint64_t TcpSocket::m_bytes_sent [private]

Definition at line 316 of file TcpSocket.h.

Referenced by GetBytesSent(), and TryWrite().

uint64_t TcpSocket::m_bytes_received [private]

Definition at line 317 of file TcpSocket.h.

Referenced by GetBytesReceived(), and OnRead().

bool TcpSocket::m_skip_c [private]

Skip second char of CRLF or LFCR sequence in OnRead.

Definition at line 318 of file TcpSocket.h.

Referenced by OnRead().

char TcpSocket::m_c [private]

First char in CRLF or LFCR sequence.

Definition at line 319 of file TcpSocket.h.

Referenced by OnRead().

std::vector<char> TcpSocket::m_line [private]

Current line in line protocol mode.

Reimplemented in HTTPSocket.

Definition at line 320 of file TcpSocket.h.

Referenced by GetLine(), and OnRead().

size_t TcpSocket::m_line_ptr [private]

Definition at line 321 of file TcpSocket.h.

Referenced by GetLine(), and OnRead().

char* TcpSocket::m_buf [private]

temporary read buffer

Definition at line 323 of file TcpSocket.h.

Referenced by OnRead(), and ~TcpSocket().

output buffer

Definition at line 325 of file TcpSocket.h.

Referenced by Buffer(), SendBuf(), SendFromOutputBuffer(), and ~TcpSocket().

output buffer on top

Definition at line 326 of file TcpSocket.h.

Referenced by Buffer(), SendBuf(), and SendFromOutputBuffer().

size_t TcpSocket::m_transfer_limit [private]

Definition at line 327 of file TcpSocket.h.

Referenced by SendFromOutputBuffer(), and SetTransferLimit().

size_t TcpSocket::m_output_length [private]

Definition at line 328 of file TcpSocket.h.

Referenced by Buffer(), GetOutputLength(), and SendFromOutputBuffer().

size_t TcpSocket::m_repeat_length [private]

Definition at line 329 of file TcpSocket.h.

Referenced by TryWrite().

Definition at line 332 of file TcpSocket.h.

SSL_CTX* TcpSocket::m_ssl_ctx [private]

ssl context

Definition at line 333 of file TcpSocket.h.

Referenced by GetSslContext(), InitializeContext(), OnSSLAccept(), OnSSLConnect(), and UseCertificateChainFile().

SSL* TcpSocket::m_ssl [private]

ssl 'socket'

Definition at line 334 of file TcpSocket.h.

Referenced by Close(), GetSsl(), OnRead(), OnSSLAccept(), OnSSLConnect(), SSLNegotiate(), TryWrite(), and ~TcpSocket().

BIO* TcpSocket::m_sbio [private]

ssl bio

Definition at line 335 of file TcpSocket.h.

Referenced by OnSSLAccept(), and OnSSLConnect().

std::string TcpSocket::m_password [private]

ssl password

Definition at line 336 of file TcpSocket.h.

Referenced by GetPassword(), and InitializeContext().

Definition at line 337 of file TcpSocket.h.

Referenced by InitializeContext().

std::map< std::string, SSL_CTX * > TcpSocket::m_client_contexts [static, private]

Definition at line 338 of file TcpSocket.h.

Referenced by InitializeContext().

std::map< std::string, SSL_CTX * > TcpSocket::m_server_contexts [static, private]

Definition at line 339 of file TcpSocket.h.

Referenced by InitializeContext().

socks4 support

Definition at line 343 of file TcpSocket.h.

Referenced by OnSocks4Connect(), and OnSocks4Read().

char TcpSocket::m_socks4_vn [private]

socks4 support, temporary variable

Definition at line 344 of file TcpSocket.h.

Referenced by OnSocks4Read().

char TcpSocket::m_socks4_cd [private]

socks4 support, temporary variable

Definition at line 345 of file TcpSocket.h.

Referenced by OnSocks4Read().

unsigned short TcpSocket::m_socks4_dstport [private]

socks4 support

Definition at line 346 of file TcpSocket.h.

Referenced by OnSocks4Read().

unsigned long TcpSocket::m_socks4_dstip [private]

socks4 support

Definition at line 347 of file TcpSocket.h.

Referenced by OnSocks4Read().

int TcpSocket::m_resolver_id [private]

Resolver id (if any) for current Open call.

Definition at line 351 of file TcpSocket.h.

Referenced by OnResolved(), and Open().

bool TcpSocket::m_b_reconnect [private]

Reconnect on lost connection flag.

Definition at line 355 of file TcpSocket.h.

Referenced by Reconnect(), and SetReconnect().

Trying to reconnect.

Definition at line 356 of file TcpSocket.h.

Referenced by IsReconnect(), and SetIsReconnect().


The documentation for this class was generated from the following files:
Page, code, and content Copyright (C) 2007 by Anders Hedström
Generated for C++ Sockets by  doxygen 1.4.4