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

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

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

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

TcpSocket::~TcpSocket (  ) 

Definition at line 160 of file TcpSocket.cpp.

References m_buf, m_obuf, and m_ssl.

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

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

Definition at line 955 of file TcpSocket.cpp.

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


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

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

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

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

Definition at line 201 of file TcpSocket.cpp.

References Open().

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

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

Connecting();

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

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

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

Open connection.

Parameters:
host Hostname
port Port number

Definition at line 334 of file TcpSocket.cpp.

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

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

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

References Send().

Referenced by HttpDebugSocket::OnFirst().

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

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

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

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

Referenced by SendFromOutputBuffer().

00670 {
00671 }

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

Referenced by OnRead().

00948 {
00949 }

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

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

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

void TcpSocket::OnSocks4ConnectFailed (  )  [virtual]

Socks4 specific callback.

Reimplemented from Socket.

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

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

bool TcpSocket::OnSocks4Read (  )  [virtual]

Socks4 specific callback.

Returns:
'need_more'

Reimplemented from Socket.

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

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

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

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

void TcpSocket::OnSSLConnect (  )  [virtual]

Callback for 'New' ssl support - replaces SSLSocket.

Internal use.

Reimplemented from Socket.

Definition at line 1092 of file TcpSocket.cpp.

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

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

void TcpSocket::OnSSLAccept (  )  [virtual]

Callback for 'New' ssl support - replaces SSLSocket.

Internal use.

Reimplemented from Socket.

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

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

void TcpSocket::InitSSLClient (  )  [virtual]

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

Definition at line 1263 of file TcpSocket.cpp.

References InitializeContext().

Referenced by OnSSLConnect().

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

void TcpSocket::InitSSLServer (  )  [virtual]

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

Definition at line 1269 of file TcpSocket.cpp.

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

Referenced by OnSSLAccept().

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

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

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

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

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

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

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

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

Reimplemented from Socket.

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

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

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

References m_client_contexts, and m_ssl_ctx.

Referenced by InitSSLClient().

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

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                 const SSL_METHOD *meth = meth_in ? meth_in : SSLv3_method();
01301                 m_ssl_ctx = m_server_contexts[context] = SSL_CTX_new(const_cast<SSL_METHOD *>(meth));
01302                 SSL_CTX_set_mode(m_ssl_ctx, SSL_MODE_AUTO_RETRY|SSL_MODE_ENABLE_PARTIAL_WRITE);
01303                 // 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                 const SSL_METHOD *meth = meth_in ? meth_in : SSLv3_method();
01337                 m_ssl_ctx = m_server_contexts[context] = SSL_CTX_new(const_cast<SSL_METHOD *>(meth));
01338                 SSL_CTX_set_mode(m_ssl_ctx, SSL_MODE_AUTO_RETRY|SSL_MODE_ENABLE_PARTIAL_WRITE);
01339                 // 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 1172 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().

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

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

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

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

the actual send()

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

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

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

add data to output buffer top

Definition at line 853 of file TcpSocket.cpp.

References m_obuf, m_obuf_top, and m_output_length.

Referenced by SendBuf().

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


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