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

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


Member Function Documentation

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

Open a connection to a remote server.

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

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

Definition at line 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(), StreamSocket::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() >= FD_SETSIZE)
00216         {
00217                 Handler().LogError(this, "Open", 0, "no space left in fd_set", 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 1708 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(), StreamSocket::SetRetryClientConnect(), and Socket::Socks4().

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

int TcpSocket::Close (  )  [virtual]

Close file descriptor - internal use only.

See also:
SetCloseAndDelete

Reimplemented from Socket.

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

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

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 #ifdef _WIN32
01085         vsprintf(slask, format, ap);
01086 #else
01087         vsnprintf(slask, 5000, format, ap);
01088 #endif
01089         va_end(ap);
01090         Send( slask );
01091 }

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

Send buffer of bytes.

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

Reimplemented from Socket.

Definition at line 893 of file TcpSocket.cpp.

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

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

00894 {
00895         if (!Ready() && !Connecting())
00896         {
00897                 Handler().LogError(this, "SendBuf", -1, "Attempt to write to a non-ready socket" ); // warning
00898                 if (GetSocket() == INVALID_SOCKET)
00899                         Handler().LogError(this, "SendBuf", 0, " * GetSocket() == INVALID_SOCKET", LOG_LEVEL_INFO);
00900                 if (Connecting())
00901                         Handler().LogError(this, "SendBuf", 0, " * Connecting()", LOG_LEVEL_INFO);
00902                 if (CloseAndDelete())
00903                         Handler().LogError(this, "SendBuf", 0, " * CloseAndDelete()", LOG_LEVEL_INFO);
00904                 return;
00905         }
00906         if (!IsConnected())
00907         {
00908                 Handler().LogError(this, "SendBuf", -1, "Attempt to write to a non-connected socket, will be sent on connect" ); // warning
00909                 Buffer(buf, len);
00910                 return;
00911         }
00912         if (m_obuf_top)
00913         {
00914                 Buffer(buf, len);
00915                 return;
00916         }
00917         if (IsSSL())
00918         {
00919                 Buffer(buf, len);
00920                 SendFromOutputBuffer();
00921                 return;
00922         }
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;
00939                 bool bw;
00940                 bool bx;
00941                 Handler().Get(GetSocket(), br, bw, bx);
00942                 if (m_obuf.size())
00943                         Set(br, true);
00944                 else
00945                         Set(br, false);
00946         }
00947 }

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

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

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

Reimplemented in AjpBaseSocket, and HTTPSocket.

Definition at line 1448 of file TcpSocket.cpp.

Referenced by OnRead().

01449 {
01450 }

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

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

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

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

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

Read from input buffer.

Definition at line 1459 of file TcpSocket.cpp.

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

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

size_t TcpSocket::GetOutputLength (  ) 

Number of bytes in output buffer.

Definition at line 1467 of file TcpSocket.cpp.

References m_output_length.

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

01468 {
01469         return m_output_length;
01470 }

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

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

Parameters:
line Line read

Reimplemented from Socket.

Reimplemented in HTTPSocket, ResolvSocket, and SmtpdSocket.

Definition at line 950 of file TcpSocket.cpp.

Referenced by OnRead().

00951 {
00952 }

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

Get counter of number of bytes received.

Reimplemented from Socket.

Definition at line 1473 of file TcpSocket.cpp.

References m_bytes_received.

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

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

Get counter of number of bytes sent.

Reimplemented from Socket.

Definition at line 1482 of file TcpSocket.cpp.

References m_bytes_sent.

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

void TcpSocket::OnSocks4Connect (  )  [virtual]

Socks4 specific callback.

Todo:
warn

Todo:
warn

Reimplemented from Socket.

Definition at line 969 of file TcpSocket.cpp.

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

00970 {
00971         char request[1000];
00972         memset(request, 0, sizeof(request));
00973         request[0] = 4; // socks v4
00974         request[1] = 1; // command code: CONNECT
00975         {
00976                 std::auto_ptr<SocketAddress> ad = GetClientRemoteAddress();
00977                 if (ad.get())
00978                 {
00979                         struct sockaddr *p0 = (struct sockaddr *)*ad;
00980                         struct sockaddr_in *p = (struct sockaddr_in *)p0;
00981                         if (p -> sin_family == AF_INET)
00982                         {
00983                                 memcpy(request + 2, &p -> sin_port, 2); // nwbo is ok here
00984                                 memcpy(request + 4, &p -> sin_addr, sizeof(struct in_addr));
00985                         }
00986                         else
00987                         {
00989                         }
00990                 }
00991                 else
00992                 {
00994                 }
00995         }
00996         strcpy(request + 8, GetSocks4Userid().c_str());
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 StreamSocket::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 1095 of file TcpSocket.cpp.

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

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

void TcpSocket::OnSSLAccept (  )  [virtual]

Callback for 'New' ssl support - replaces SSLSocket.

Internal use.

Reimplemented from Socket.

Definition at line 1137 of file TcpSocket.cpp.

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

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

void TcpSocket::InitSSLClient (  )  [virtual]

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

Definition at line 1266 of file TcpSocket.cpp.

References InitializeContext().

Referenced by OnSSLConnect().

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

void TcpSocket::InitSSLServer (  )  [virtual]

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

Definition at line 1272 of file TcpSocket.cpp.

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

Referenced by OnSSLAccept().

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

void TcpSocket::SetReconnect ( bool  x = true  ) 

Flag that says a broken connection will try to reconnect.

Definition at line 1441 of file TcpSocket.cpp.

References m_b_reconnect.

01442 {
01443         m_b_reconnect = x;
01444 }

bool TcpSocket::Reconnect (  ) 

Check reconnect on lost connection flag status.

Definition at line 1492 of file TcpSocket.cpp.

References m_b_reconnect.

Referenced by Open().

01493 {
01494         return m_b_reconnect;
01495 }

void TcpSocket::SetIsReconnect ( bool  x = true  ) 

Flag to determine if a reconnect is in progress.

Definition at line 1498 of file TcpSocket.cpp.

References m_b_is_reconnect.

01499 {
01500         m_b_is_reconnect = x;
01501 }

bool TcpSocket::IsReconnect (  ) 

Socket is reconnecting.

Definition at line 1504 of file TcpSocket.cpp.

References m_b_is_reconnect.

Referenced by SSLNegotiate().

01505 {
01506         return m_b_is_reconnect;
01507 }

void TcpSocket::DisableInputBuffer ( bool  x = true  ) 

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

Definition at line 1519 of file TcpSocket.cpp.

References m_b_input_buffer_disabled.

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

01520 {
01521         m_b_input_buffer_disabled = x;
01522 }

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

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

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

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

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

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

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

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

References m_line, and m_line_ptr.

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

bool TcpSocket::SetTcpNodelay ( bool  x = true  ) 

Definition at line 1551 of file TcpSocket.cpp.

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

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

int TcpSocket::Protocol (  )  [virtual]

Returns IPPROTO_TCP or IPPROTO_SCTP.

Implements StreamSocket.

Definition at line 1782 of file TcpSocket.cpp.

01783 {
01784         return IPPROTO_TCP;
01785 }

void TcpSocket::SetTransferLimit ( size_t  sz  ) 

Trigger limit for callback OnTransferLimit.

Definition at line 1788 of file TcpSocket.cpp.

References m_transfer_limit.

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

01789 {
01790         m_transfer_limit = sz;
01791 }

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

Referenced by SendFromOutputBuffer().

01795 {
01796 }

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", 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", 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(), LOG_LEVEL_FATAL, ISocketHandler::LogError(), Socket::OnConnectFailed(), OnSocks4ConnectFailed(), SendFromOutputBuffer(), Socket::Set(), StreamSocket::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                         Set(!IsDisableRead(), false);
00683                         SetConnecting(false);
00684                         SetCallOnConnect();
00685                         return;
00686                 }
00687                 Handler().LogError(this, "tcp: connect failed", err, StrError(err), LOG_LEVEL_FATAL);
00688                 Set(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 1279 of file TcpSocket.cpp.

References m_client_contexts, and m_ssl_ctx.

Referenced by InitSSLClient().

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

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

SSL; Initialize ssl context for a server socket.

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

Definition at line 1297 of file TcpSocket.cpp.

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

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

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

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

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

SSL; Password callback method.

Definition at line 1369 of file TcpSocket.cpp.

References GetPassword().

Referenced by InitializeContext().

01370 {
01371         Socket *p0 = static_cast<Socket *>(userdata);
01372         TcpSocket *p = dynamic_cast<TcpSocket *>(p0);
01373         std::string pw = p ? p -> GetPassword() : "";
01374         if ( (size_t)num < pw.size() + 1)
01375         {
01376                 return 0;
01377         }
01378         strcpy(buf,pw.c_str());
01379         return (int)pw.size();
01380 }

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

SSL; Get pointer to ssl context structure.

Reimplemented from Socket.

Definition at line 1424 of file TcpSocket.cpp.

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

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

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

SSL; Get pointer to ssl structure.

Reimplemented from Socket.

Definition at line 1431 of file TcpSocket.cpp.

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

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

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

ssl; still negotiating connection.

Todo:
: resurrect certificate check... client

Todo:
: resurrect certificate check... server

Reimplemented from Socket.

Definition at line 1175 of file TcpSocket.cpp.

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

Referenced by OnSSLConnect().

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

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

SSL; Get ssl password.

Definition at line 1512 of file TcpSocket.cpp.

References m_password.

Referenced by SSL_password_cb().

01513 {
01514         return m_password;
01515 }

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 ISocketHandler::Get(), GetOutputLength(), Socket::GetSocket(), Socket::Handler(), LOG_LEVEL_ERROR, ISocketHandler::LogError(), m_obuf, m_obuf_top, m_output_length, m_transfer_limit, OnTransferLimit(), OnWriteComplete(), Socket::Set(), 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", 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;
00767                 bool bw;
00768                 bool bx;
00769                 Handler().Get(GetSocket(), br, bw, bx);
00770                 if (m_obuf.size())
00771                         Set(br, true);
00772                 else
00773                         Set(br, false);
00774         }
00775 }

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

the actual send()

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

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

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

add data to output buffer top

Definition at line 855 of file TcpSocket.cpp.

References m_obuf, m_obuf_top, and m_output_length.

Referenced by SendBuf().

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


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