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.
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 82 of file TcpSocket.cpp.

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

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 122 of file TcpSocket.cpp.

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

TcpSocket::~TcpSocket (  ) 

Definition at line 159 of file TcpSocket.cpp.

References m_buf, m_obuf, and m_ssl.

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

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

Definition at line 954 of file TcpSocket.cpp.

00955 :StreamSocket(s)
00956 ,ibuf(0)
00957 {
00958 }


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 181 of file TcpSocket.cpp.

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

00182 {
00183         Ipv4Address ad(ip, port);
00184         Ipv4Address local;
00185         return Open(ad, local, skip_socks);
00186 }

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

Definition at line 200 of file TcpSocket.cpp.

References Open().

00201 {
00202         Ipv4Address bind_ad("0.0.0.0", 0);
00203         return Open(ad, bind_ad, skip_socks);
00204 }

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

Connecting();

Definition at line 207 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.

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

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

Open connection.

Parameters:
host Hostname
port Port number

Definition at line 333 of file TcpSocket.cpp.

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

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

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 1709 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().

01710 {
01711         Handler().LogError(this, "connect", -1, "connect timeout", LOG_LEVEL_FATAL);
01712 #ifdef ENABLE_SOCKS4
01713         if (Socks4())
01714         {
01715                 OnSocks4ConnectFailed();
01716                 // retry direct connection
01717         }
01718         else
01719 #endif
01720         if (GetConnectionRetry() == -1 ||
01721                 (GetConnectionRetry() && GetConnectionRetries() < GetConnectionRetry()) )
01722         {
01723                 IncreaseConnectionRetries();
01724                 // ask socket via OnConnectRetry callback if we should continue trying
01725                 if (OnConnectRetry())
01726                 {
01727                         SetRetryClientConnect();
01728                 }
01729                 else
01730                 {
01731                         SetCloseAndDelete( true );
01733                         OnConnectFailed();
01734                         //
01735                         SetConnecting(false);
01736                 }
01737         }
01738         else
01739         {
01740                 SetCloseAndDelete(true);
01742                 OnConnectFailed();
01743                 //
01744                 SetConnecting(false);
01745         }
01746 }

int TcpSocket::Close (  )  [virtual]

Close file descriptor - internal use only.

See also:
SetCloseAndDelete

Reimplemented from Socket.

Definition at line 1385 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.

01386 {
01387         if (GetSocket() == INVALID_SOCKET) // this could happen
01388         {
01389                 Handler().LogError(this, "Socket::Close", 0, "file descriptor invalid", LOG_LEVEL_WARNING);
01390                 return 0;
01391         }
01392         int n;
01393         SetNonblocking(true);
01394         if (!Lost() && IsConnected() && !(GetShutdown() & SHUT_WR))
01395         {
01396                 if (shutdown(GetSocket(), SHUT_WR) == -1)
01397                 {
01398                         // failed...
01399                         Handler().LogError(this, "shutdown", Errno, StrError(Errno), LOG_LEVEL_ERROR);
01400                 }
01401         }
01402         //
01403         char tmp[1000];
01404         if (!Lost() && (n = recv(GetSocket(),tmp,1000,0)) >= 0)
01405         {
01406                 if (n)
01407                 {
01408                         Handler().LogError(this, "read() after shutdown", n, "bytes read", LOG_LEVEL_WARNING);
01409                 }
01410         }
01411 #ifdef HAVE_OPENSSL
01412         if (IsSSL() && m_ssl)
01413                 SSL_shutdown(m_ssl);
01414         if (m_ssl)
01415         {
01416                 SSL_free(m_ssl);
01417                 m_ssl = NULL;
01418         }
01419 #endif
01420         return Socket::Close();
01421 }

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 1079 of file TcpSocket.cpp.

References Send().

Referenced by HttpDebugSocket::OnFirst().

01080 {
01081         va_list ap;
01082         va_start(ap, format);
01083         char slask[5000]; // vsprintf / vsnprintf temporary
01084         vsnprintf(slask, sizeof(slask), format, ap);
01085         va_end(ap);
01086         Send( slask );
01087 }

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 890 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(), HttpPutSocket::OnConnect(), HttpDebugSocket::OnData(), OnSocks4Connect(), HttpBaseSocket::OnTransferLimit(), Ajp13Socket::OnTransferLimit(), Ajp13Socket::ReceiveBody(), Ajp13Socket::Respond(), Send(), and HttpdSocket::Send64().

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

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 1449 of file TcpSocket.cpp.

Referenced by OnRead().

01450 {
01451 }

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 668 of file TcpSocket.cpp.

Referenced by SendFromOutputBuffer().

00669 {
00670 }

size_t TcpSocket::GetInputLength (  ) 

Number of bytes in input buffer.

Definition at line 1454 of file TcpSocket.cpp.

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

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

01455 {
01456         return ibuf.GetLength();
01457 }

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

Read from input buffer.

Definition at line 1460 of file TcpSocket.cpp.

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

01461 {
01462         size_t sz = max_sz < GetInputLength() ? max_sz : GetInputLength();
01463         ibuf.Read(buf, sz);
01464         return sz;
01465 }

size_t TcpSocket::GetOutputLength (  ) 

Number of bytes in output buffer.

Definition at line 1468 of file TcpSocket.cpp.

References m_output_length.

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

01469 {
01470         return m_output_length;
01471 }

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 946 of file TcpSocket.cpp.

Referenced by OnRead().

00947 {
00948 }

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

Get counter of number of bytes received.

Reimplemented from Socket.

Definition at line 1474 of file TcpSocket.cpp.

References m_bytes_received.

01475 {
01476         uint64_t z = m_bytes_received;
01477         if (clear)
01478                 m_bytes_received = 0;
01479         return z;
01480 }

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

Get counter of number of bytes sent.

Reimplemented from Socket.

Definition at line 1483 of file TcpSocket.cpp.

References m_bytes_sent.

01484 {
01485         uint64_t z = m_bytes_sent;
01486         if (clear)
01487                 m_bytes_sent = 0;
01488         return z;
01489 }

void TcpSocket::OnSocks4Connect (  )  [virtual]

Socks4 specific callback.

Todo:
warn

Todo:
warn

Reimplemented from Socket.

Definition at line 965 of file TcpSocket.cpp.

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

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

void TcpSocket::OnSocks4ConnectFailed (  )  [virtual]

Socks4 specific callback.

Reimplemented from Socket.

Definition at line 1003 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().

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

bool TcpSocket::OnSocks4Read (  )  [virtual]

Socks4 specific callback.

Returns:
'need_more'

Reimplemented from Socket.

Definition at line 1019 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().

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

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 383 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().

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

void TcpSocket::OnSSLConnect (  )  [virtual]

Callback for 'New' ssl support - replaces SSLSocket.

Internal use.

Reimplemented from Socket.

Definition at line 1091 of file TcpSocket.cpp.

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

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

void TcpSocket::OnSSLAccept (  )  [virtual]

Callback for 'New' ssl support - replaces SSLSocket.

Internal use.

Reimplemented from Socket.

Definition at line 1133 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().

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

void TcpSocket::InitSSLClient (  )  [virtual]

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

Definition at line 1262 of file TcpSocket.cpp.

References InitializeContext().

Referenced by OnSSLConnect().

01263 {
01264         InitializeContext("", SSLv23_method());
01265 }

void TcpSocket::InitSSLServer (  )  [virtual]

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

Definition at line 1268 of file TcpSocket.cpp.

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

Referenced by OnSSLAccept().

01269 {
01270         Handler().LogError(this, "InitSSLServer", 0, "You MUST implement your own InitSSLServer method", LOG_LEVEL_FATAL);
01271         SetCloseAndDelete();
01272 }

void TcpSocket::SetReconnect ( bool  x = true  ) 

Flag that says a broken connection will try to reconnect.

Definition at line 1442 of file TcpSocket.cpp.

References m_b_reconnect.

01443 {
01444         m_b_reconnect = x;
01445 }

bool TcpSocket::Reconnect (  ) 

Check reconnect on lost connection flag status.

Definition at line 1493 of file TcpSocket.cpp.

References m_b_reconnect.

Referenced by Open().

01494 {
01495         return m_b_reconnect;
01496 }

void TcpSocket::SetIsReconnect ( bool  x = true  ) 

Flag to determine if a reconnect is in progress.

Definition at line 1499 of file TcpSocket.cpp.

References m_b_is_reconnect.

01500 {
01501         m_b_is_reconnect = x;
01502 }

bool TcpSocket::IsReconnect (  ) 

Socket is reconnecting.

Definition at line 1505 of file TcpSocket.cpp.

References m_b_is_reconnect.

Referenced by SSLNegotiate().

01506 {
01507         return m_b_is_reconnect;
01508 }

void TcpSocket::DisableInputBuffer ( bool  x = true  ) 

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

Definition at line 1520 of file TcpSocket.cpp.

References m_b_input_buffer_disabled.

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

01521 {
01522         m_b_input_buffer_disabled = x;
01523 }

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 1526 of file TcpSocket.cpp.

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

01527 {
01528 DEB(    fprintf(stderr, "Socket::OnOptions()\n");)
01529 #ifdef SO_NOSIGPIPE
01530         SetSoNosigpipe(true);
01531 #endif
01532         SetSoReuseaddr(true);
01533         SetSoKeepalive(true);
01534 }

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 1537 of file TcpSocket.cpp.

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

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

01538 {
01539         StreamSocket::SetLineProtocol(x);
01540         DisableInputBuffer(x);
01541 }

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 1544 of file TcpSocket.cpp.

References m_line, and m_line_ptr.

01545 {
01546         if (!m_line_ptr)
01547                 return "";
01548         return std::string(&m_line[0], m_line_ptr);
01549 }

bool TcpSocket::SetTcpNodelay ( bool  x = true  ) 

Definition at line 1552 of file TcpSocket.cpp.

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

01553 {
01554 #ifdef TCP_NODELAY
01555         int optval = x ? 1 : 0;
01556         if (setsockopt(GetSocket(), IPPROTO_TCP, TCP_NODELAY, (char *)&optval, sizeof(optval)) == -1)
01557         {
01558                 Handler().LogError(this, "setsockopt(IPPROTO_TCP, TCP_NODELAY)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
01559                 return false;
01560         }
01561         return true;
01562 #else
01563         Handler().LogError(this, "socket option not available", 0, "TCP_NODELAY", LOG_LEVEL_INFO);
01564         return false;
01565 #endif
01566 }

int TcpSocket::Protocol (  )  [virtual]

Returns IPPROTO_TCP or IPPROTO_SCTP.

Implements StreamSocket.

Definition at line 1785 of file TcpSocket.cpp.

01786 {
01787         return IPPROTO_TCP;
01788 }

void TcpSocket::SetTransferLimit ( size_t  sz  ) 

Trigger limit for callback OnTransferLimit.

Definition at line 1791 of file TcpSocket.cpp.

References m_transfer_limit.

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

01792 {
01793         m_transfer_limit = sz;
01794 }

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 1797 of file TcpSocket.cpp.

Referenced by SendFromOutputBuffer().

01798 {
01799 }

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

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

Reimplemented from Socket.

Definition at line 442 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().

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

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

Definition at line 567 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.

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

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

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

Reimplemented from Socket.

Definition at line 673 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().

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

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 1275 of file TcpSocket.cpp.

References m_client_contexts, and m_ssl_ctx.

Referenced by InitSSLClient().

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

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 1294 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().

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

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 1330 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().

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

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

SSL; Password callback method.

Definition at line 1366 of file TcpSocket.cpp.

References GetPassword().

Referenced by InitializeContext().

01367 {
01368         Socket *p0 = static_cast<Socket *>(userdata);
01369         TcpSocket *p = dynamic_cast<TcpSocket *>(p0);
01370         std::string pw = p ? p -> GetPassword() : "";
01371         if ( (size_t)num < pw.size() + 1)
01372         {
01373                 return 0;
01374         }
01375 #if defined( _WIN32) && !defined(__CYGWIN__)
01376         strcpy_s(buf, num, pw.c_str());
01377 #else
01378         strcpy(buf,pw.c_str());
01379 #endif
01380         return (int)pw.size();
01381 }

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

SSL; Get pointer to ssl context structure.

Reimplemented from Socket.

Definition at line 1425 of file TcpSocket.cpp.

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

01426 {
01427         if (!m_ssl_ctx)
01428                 Handler().LogError(this, "GetSslContext", 0, "SSL Context is NULL; check InitSSLServer/InitSSLClient", LOG_LEVEL_WARNING);
01429         return m_ssl_ctx;
01430 }

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

SSL; Get pointer to ssl structure.

Reimplemented from Socket.

Definition at line 1432 of file TcpSocket.cpp.

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

01433 {
01434         if (!m_ssl)
01435                 Handler().LogError(this, "GetSsl", 0, "SSL is NULL; check InitSSLServer/InitSSLClient", LOG_LEVEL_WARNING);
01436         return m_ssl;
01437 }

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 1171 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().

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

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

SSL; Get ssl password.

Definition at line 1513 of file TcpSocket.cpp.

References m_password.

Referenced by SSL_password_cb().

01514 {
01515         return m_password;
01516 }

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

Definition at line 303 of file TcpSocket.h.

00303 { return *this; }

void TcpSocket::SendFromOutputBuffer (  )  [private]

Definition at line 719 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().

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

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

the actual send()

Definition at line 775 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().

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

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

add data to output buffer top

Definition at line 852 of file TcpSocket.cpp.

References m_obuf, m_obuf_top, and m_output_length.

Referenced by SendBuf().

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


Member Data Documentation

Circular input buffer.

Definition at line 300 of file TcpSocket.h.

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

Definition at line 313 of file TcpSocket.h.

Referenced by DisableInputBuffer(), and OnRead().

uint64_t TcpSocket::m_bytes_sent [private]

Definition at line 314 of file TcpSocket.h.

Referenced by GetBytesSent(), and TryWrite().

uint64_t TcpSocket::m_bytes_received [private]

Definition at line 315 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 316 of file TcpSocket.h.

Referenced by OnRead().

char TcpSocket::m_c [private]

First char in CRLF or LFCR sequence.

Definition at line 317 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 318 of file TcpSocket.h.

Referenced by GetLine(), and OnRead().

size_t TcpSocket::m_line_ptr [private]

Definition at line 319 of file TcpSocket.h.

Referenced by GetLine(), and OnRead().

char* TcpSocket::m_buf [private]

temporary read buffer

Definition at line 321 of file TcpSocket.h.

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

output buffer

Definition at line 323 of file TcpSocket.h.

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

output buffer on top

Definition at line 324 of file TcpSocket.h.

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

size_t TcpSocket::m_transfer_limit [private]

Definition at line 325 of file TcpSocket.h.

Referenced by SendFromOutputBuffer(), and SetTransferLimit().

size_t TcpSocket::m_output_length [private]

Definition at line 326 of file TcpSocket.h.

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

size_t TcpSocket::m_repeat_length [private]

Definition at line 327 of file TcpSocket.h.

Referenced by TryWrite().

Definition at line 330 of file TcpSocket.h.

SSL_CTX* TcpSocket::m_ssl_ctx [private]

ssl context

Definition at line 331 of file TcpSocket.h.

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

SSL* TcpSocket::m_ssl [private]

ssl 'socket'

Definition at line 332 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 333 of file TcpSocket.h.

Referenced by OnSSLAccept(), and OnSSLConnect().

std::string TcpSocket::m_password [private]

ssl password

Definition at line 334 of file TcpSocket.h.

Referenced by GetPassword(), and InitializeContext().

Definition at line 335 of file TcpSocket.h.

Referenced by InitializeContext().

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

Definition at line 336 of file TcpSocket.h.

Referenced by InitializeContext().

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

Definition at line 337 of file TcpSocket.h.

Referenced by InitializeContext().

socks4 support

Definition at line 341 of file TcpSocket.h.

Referenced by OnSocks4Connect(), and OnSocks4Read().

char TcpSocket::m_socks4_vn [private]

socks4 support, temporary variable

Definition at line 342 of file TcpSocket.h.

Referenced by OnSocks4Read().

char TcpSocket::m_socks4_cd [private]

socks4 support, temporary variable

Definition at line 343 of file TcpSocket.h.

Referenced by OnSocks4Read().

unsigned short TcpSocket::m_socks4_dstport [private]

socks4 support

Definition at line 344 of file TcpSocket.h.

Referenced by OnSocks4Read().

unsigned long TcpSocket::m_socks4_dstip [private]

socks4 support

Definition at line 345 of file TcpSocket.h.

Referenced by OnSocks4Read().

int TcpSocket::m_resolver_id [private]

Resolver id (if any) for current Open call.

Definition at line 349 of file TcpSocket.h.

Referenced by OnResolved(), and Open().

bool TcpSocket::m_b_reconnect [private]

Reconnect on lost connection flag.

Definition at line 353 of file TcpSocket.h.

Referenced by Reconnect(), and SetReconnect().

Trying to reconnect.

Definition at line 354 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