![]() |
TcpSocket Class ReferenceSocket implementation for TCP.
More...
|
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 | 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) |
void | OnOptions (int, int, int, SOCKET) |
Called when a client socket is created, to set socket options. | |
void | SetLineProtocol (bool=true) |
Enable the OnLine callback. | |
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 | OnWrite () |
Called when there is room for another write on the file descriptor. | |
void | InitializeContext (const std::string &context, 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, 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 | |
TcpSocket & | operator= (const TcpSocket &) |
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::string | m_line |
Current line in line protocol mode. | |
char * | m_buf |
temporary read buffer | |
output_l | m_obuf |
output buffer | |
OUTPUT * | m_obuf_top |
output buffer on top | |
size_t | m_transfer_limit |
size_t | m_output_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 |
Classes | |
class | CircularBuffer |
Buffer class containing one read/write circular buffer. More... | |
struct | OUTPUT |
Output buffer struct. More... |
Definition at line 53 of file TcpSocket.h.
typedef std::list<OUTPUT *> TcpSocket::output_l [protected] |
Definition at line 127 of file TcpSocket.h.
TcpSocket::TcpSocket | ( | ISocketHandler & | ) |
Constructor with standard values on input/output buffers.
Definition at line 74 of file TcpSocket.cpp.
00074 : StreamSocket(h) 00075 ,ibuf(TCP_BUFSIZE_READ) 00076 ,m_b_input_buffer_disabled(false) 00077 ,m_bytes_sent(0) 00078 ,m_bytes_received(0) 00079 ,m_skip_c(false) 00080 #ifdef SOCKETS_DYNAMIC_TEMP 00081 ,m_buf(new char[TCP_BUFSIZE_READ + 1]) 00082 #endif 00083 ,m_obuf_top(NULL) 00084 ,m_transfer_limit(0) 00085 ,m_output_length(0) 00086 #ifdef HAVE_OPENSSL 00087 ,m_ssl_ctx(NULL) 00088 ,m_ssl(NULL) 00089 ,m_sbio(NULL) 00090 #endif 00091 #ifdef ENABLE_SOCKS4 00092 ,m_socks4_state(0) 00093 #endif 00094 #ifdef ENABLE_RESOLVER 00095 ,m_resolver_id(0) 00096 #endif 00097 #ifdef ENABLE_RECONNECT 00098 ,m_b_reconnect(false) 00099 ,m_b_is_reconnect(false) 00100 #endif 00101 { 00102 }
TcpSocket::TcpSocket | ( | ISocketHandler & | h, | |
size_t | isize, | |||
size_t | osize | |||
) |
Constructor with custom values for i/o buffer.
h | ISocketHandler reference | |
isize | Input buffer size | |
osize | Output buffer size |
Definition at line 111 of file TcpSocket.cpp.
00111 : StreamSocket(h) 00112 ,ibuf(isize) 00113 ,m_b_input_buffer_disabled(false) 00114 ,m_bytes_sent(0) 00115 ,m_bytes_received(0) 00116 ,m_skip_c(false) 00117 #ifdef SOCKETS_DYNAMIC_TEMP 00118 ,m_buf(new char[TCP_BUFSIZE_READ + 1]) 00119 #endif 00120 ,m_obuf_top(NULL) 00121 ,m_transfer_limit(0) 00122 ,m_output_length(0) 00123 #ifdef HAVE_OPENSSL 00124 ,m_ssl_ctx(NULL) 00125 ,m_ssl(NULL) 00126 ,m_sbio(NULL) 00127 #endif 00128 #ifdef ENABLE_SOCKS4 00129 ,m_socks4_state(0) 00130 #endif 00131 #ifdef ENABLE_RESOLVER 00132 ,m_resolver_id(0) 00133 #endif 00134 #ifdef ENABLE_RECONNECT 00135 ,m_b_reconnect(false) 00136 ,m_b_is_reconnect(false) 00137 #endif 00138 { 00139 }
TcpSocket::~TcpSocket | ( | ) |
TcpSocket::TcpSocket | ( | const TcpSocket & | ) | [protected] |
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...
ip | IP address | |
port | Port number | |
skip_socks | Do not use socks4 even if configured |
Definition at line 160 of file TcpSocket.cpp.
Referenced by HttpGetSocket::HttpGetSocket(), OnResolved(), Open(), HttpPutSocket::Open(), and HttpPostSocket::Open().
00161 { 00162 Ipv4Address ad(ip, port); 00163 Ipv4Address local; 00164 return Open(ad, local, skip_socks); 00165 }
bool TcpSocket::Open | ( | SocketAddress & | , | |
bool | skip_socks = false | |||
) |
Definition at line 179 of file TcpSocket.cpp.
References Open().
00180 { 00181 Ipv4Address bind_ad("0.0.0.0", 0); 00182 return Open(ad, bind_ad, skip_socks); 00183 }
bool TcpSocket::Open | ( | SocketAddress & | , | |
SocketAddress & | bind_address, | |||
bool | skip_socks = false | |||
) |
Definition at line 186 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.
00187 { 00188 if (!ad.IsValid()) 00189 { 00190 Handler().LogError(this, "Open", 0, "Invalid SocketAddress", LOG_LEVEL_FATAL); 00191 SetCloseAndDelete(); 00192 return false; 00193 } 00194 if (Handler().GetCount() >= FD_SETSIZE) 00195 { 00196 Handler().LogError(this, "Open", 0, "no space left in fd_set", LOG_LEVEL_FATAL); 00197 SetCloseAndDelete(); 00198 return false; 00199 } 00200 SetConnecting(false); 00201 #ifdef ENABLE_SOCKS4 00202 SetSocks4(false); 00203 #endif 00204 // check for pooling 00205 #ifdef ENABLE_POOL 00206 if (Handler().PoolEnabled()) 00207 { 00208 ISocketHandler::PoolSocket *pools = Handler().FindConnection(SOCK_STREAM, "tcp", ad); 00209 if (pools) 00210 { 00211 CopyConnection( pools ); 00212 delete pools; 00213 00214 SetIsClient(); 00215 SetCallOnConnect(); // ISocketHandler must call OnConnect 00216 Handler().LogError(this, "SetCallOnConnect", 0, "Found pooled connection", LOG_LEVEL_INFO); 00217 return true; 00218 } 00219 } 00220 #endif 00221 // if not, create new connection 00222 SOCKET s = CreateSocket(ad.GetFamily(), SOCK_STREAM, "tcp"); 00223 if (s == INVALID_SOCKET) 00224 { 00225 return false; 00226 } 00227 // socket must be nonblocking for async connect 00228 if (!SetNonblocking(true, s)) 00229 { 00230 SetCloseAndDelete(); 00231 closesocket(s); 00232 return false; 00233 } 00234 #ifdef ENABLE_POOL 00235 SetIsClient(); // client because we connect 00236 #endif 00237 SetClientRemoteAddress(ad); 00238 int n = 0; 00239 if (bind_ad.GetPort() != 0) 00240 { 00241 bind(s, bind_ad, bind_ad); 00242 } 00243 #ifdef ENABLE_SOCKS4 00244 if (!skip_socks && GetSocks4Host() && GetSocks4Port()) 00245 { 00246 Ipv4Address sa(GetSocks4Host(), GetSocks4Port()); 00247 { 00248 std::string sockshost; 00249 Utility::l2ip(GetSocks4Host(), sockshost); 00250 Handler().LogError(this, "Open", 0, "Connecting to socks4 server @ " + sockshost + ":" + 00251 Utility::l2string(GetSocks4Port()), LOG_LEVEL_INFO); 00252 } 00253 SetSocks4(); 00254 n = connect(s, sa, sa); 00255 SetRemoteAddress(sa); 00256 } 00257 else 00258 #endif 00259 { 00260 n = connect(s, ad, ad); 00261 SetRemoteAddress(ad); 00262 } 00263 if (n == -1) 00264 { 00265 // check error code that means a connect is in progress 00266 #ifdef _WIN32 00267 if (Errno == WSAEWOULDBLOCK) 00268 #else 00269 if (Errno == EINPROGRESS) 00270 #endif 00271 { 00272 Attach(s); 00273 SetConnecting( true ); // this flag will control fd_set's 00274 } 00275 else 00276 #ifdef ENABLE_SOCKS4 00277 if (Socks4() && Handler().Socks4TryDirect() ) // retry 00278 { 00279 closesocket(s); 00280 return Open(ad, true); 00281 } 00282 else 00283 #endif 00284 #ifdef ENABLE_RECONNECT 00285 if (Reconnect()) 00286 { 00287 Handler().LogError(this, "connect: failed, reconnect pending", Errno, StrError(Errno), LOG_LEVEL_INFO); 00288 Attach(s); 00289 SetConnecting( true ); // this flag will control fd_set's 00290 } 00291 else 00292 #endif 00293 { 00294 Handler().LogError(this, "connect: failed", Errno, StrError(Errno), LOG_LEVEL_FATAL); 00295 SetCloseAndDelete(); 00296 closesocket(s); 00297 return false; 00298 } 00299 } 00300 else 00301 { 00302 Attach(s); 00303 SetCallOnConnect(); // ISocketHandler must call OnConnect 00304 } 00305 00306 // 'true' means connected or connecting(not yet connected) 00307 // 'false' means something failed 00308 return true; 00309 }
bool TcpSocket::Open | ( | const std::string & | host, | |
port_t | port | |||
) |
Open connection.
host | Hostname | |
port | Port number |
Definition at line 312 of file TcpSocket.cpp.
References Socket::Handler(), Utility::isipv4(), Utility::isipv6(), m_resolver_id, Open(), Socket::Resolve(), Socket::SetCloseAndDelete(), and Utility::u2ip().
00313 { 00314 #ifdef ENABLE_IPV6 00315 #ifdef IPPROTO_IPV6 00316 if (IsIpv6()) 00317 { 00318 #ifdef ENABLE_RESOLVER 00319 if (!Handler().ResolverEnabled() || Utility::isipv6(host) ) 00320 { 00321 #endif 00322 in6_addr a; 00323 if (!Utility::u2ip(host, a)) 00324 { 00325 SetCloseAndDelete(); 00326 return false; 00327 } 00328 Ipv6Address ad(a, port); 00329 Ipv6Address local; 00330 return Open(ad, local); 00331 #ifdef ENABLE_RESOLVER 00332 } 00333 m_resolver_id = Resolve6(host, port); 00334 return true; 00335 #endif 00336 } 00337 #endif 00338 #endif 00339 #ifdef ENABLE_RESOLVER 00340 if (!Handler().ResolverEnabled() || Utility::isipv4(host) ) 00341 { 00342 #endif 00343 ipaddr_t l; 00344 if (!Utility::u2ip(host,l)) 00345 { 00346 SetCloseAndDelete(); 00347 return false; 00348 } 00349 Ipv4Address ad(l, port); 00350 Ipv4Address local; 00351 return Open(ad, local); 00352 #ifdef ENABLE_RESOLVER 00353 } 00354 // resolve using async resolver thread 00355 m_resolver_id = Resolve(host, port); 00356 return true; 00357 #endif 00358 }
void TcpSocket::OnConnectTimeout | ( | ) | [virtual] |
Connect timeout callback.
Reimplemented from Socket.
Definition at line 1587 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().
01588 { 01589 Handler().LogError(this, "connect", -1, "connect timeout", LOG_LEVEL_FATAL); 01590 #ifdef ENABLE_SOCKS4 01591 if (Socks4()) 01592 { 01593 OnSocks4ConnectFailed(); 01594 // retry direct connection 01595 } 01596 else 01597 #endif 01598 if (GetConnectionRetry() == -1 || 01599 (GetConnectionRetry() && GetConnectionRetries() < GetConnectionRetry()) ) 01600 { 01601 IncreaseConnectionRetries(); 01602 // ask socket via OnConnectRetry callback if we should continue trying 01603 if (OnConnectRetry()) 01604 { 01605 SetRetryClientConnect(); 01606 } 01607 else 01608 { 01609 SetCloseAndDelete( true ); 01611 OnConnectFailed(); 01612 } 01613 } 01614 else 01615 { 01616 SetCloseAndDelete(true); 01618 OnConnectFailed(); 01619 } 01620 // 01621 SetConnecting(false); 01622 }
int TcpSocket::Close | ( | ) | [virtual] |
Close file descriptor - internal use only.
Reimplemented from Socket.
Definition at line 1273 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(), m_ssl, Socket::SetNonblocking(), and StrError.
01274 { 01275 if (GetSocket() == INVALID_SOCKET) // this could happen 01276 { 01277 Handler().LogError(this, "Socket::Close", 0, "file descriptor invalid", LOG_LEVEL_WARNING); 01278 return 0; 01279 } 01280 int n; 01281 SetNonblocking(true); 01282 if (IsConnected() && !(GetShutdown() & SHUT_WR)) 01283 { 01284 if (shutdown(GetSocket(), SHUT_WR) == -1) 01285 { 01286 // failed... 01287 Handler().LogError(this, "shutdown", Errno, StrError(Errno), LOG_LEVEL_ERROR); 01288 } 01289 } 01290 // 01291 char tmp[1000]; 01292 if ((n = recv(GetSocket(),tmp,1000,0)) >= 0) 01293 { 01294 if (n) 01295 { 01296 Handler().LogError(this, "read() after shutdown", n, "bytes read", LOG_LEVEL_WARNING); 01297 } 01298 } 01299 #ifdef HAVE_OPENSSL 01300 if (IsSSL() && m_ssl) 01301 SSL_shutdown(m_ssl); 01302 if (m_ssl) 01303 { 01304 SSL_free(m_ssl); 01305 m_ssl = NULL; 01306 } 01307 #endif 01308 return Socket::Close(); 01309 }
void TcpSocket::Send | ( | const std::string & | s, | |
int | f = 0 | |||
) | [virtual] |
Send a string.
s | String to send | |
f | Dummy flags -- not used |
Reimplemented from Socket.
Definition at line 811 of file TcpSocket.cpp.
References SendBuf().
Referenced by HttpPostSocket::DoMultipartPost(), SmtpdSocket::OnAccept(), ResolvSocket::OnConnect(), HttpPostSocket::OnConnect(), HttpDebugSocket::OnData(), ResolvSocket::OnDetached(), HttpDebugSocket::OnFirst(), HttpDebugSocket::OnHeader(), HttpDebugSocket::OnHeaderComplete(), SmtpdSocket::OnLine(), ResolvSocket::OnLine(), Sendf(), HTTPSocket::SendRequest(), and HTTPSocket::SendResponse().
00812 { 00813 SendBuf(str.c_str(),str.size(),i); 00814 }
void TcpSocket::Sendf | ( | const char * | format, | |
... | ||||
) |
Send string using printf formatting.
Definition at line 997 of file TcpSocket.cpp.
References Send().
00998 { 00999 va_list ap; 01000 va_start(ap, format); 01001 char slask[5000]; // vsprintf / vsnprintf temporary 01002 #ifdef _WIN32 01003 vsprintf(slask, format, ap); 01004 #else 01005 vsnprintf(slask, 5000, format, ap); 01006 #endif 01007 va_end(ap); 01008 Send( slask ); 01009 }
void TcpSocket::SendBuf | ( | const char * | buf, | |
size_t | len, | |||
int | f = 0 | |||
) | [virtual] |
Send buffer of bytes.
buf | Buffer pointer | |
len | Length of data | |
f | Dummy flags -- not used |
Reimplemented from Socket.
Definition at line 817 of file TcpSocket.cpp.
References Buffer(), Socket::CloseAndDelete(), StreamSocket::Connecting(), ISocketHandler::Get(), Socket::GetSocket(), Socket::Handler(), INVALID_SOCKET, Socket::IsConnected(), LOG_LEVEL_INFO, ISocketHandler::LogError(), m_obuf, m_obuf_top, StreamSocket::Ready(), Socket::Set(), and TryWrite().
Referenced by HttpPostSocket::DoMultipartPost(), HttpPutSocket::OnConnect(), HttpDebugSocket::OnData(), OnSocks4Connect(), Send(), and HttpdSocket::Send64().
00818 { 00819 if (!Ready() && !Connecting()) 00820 { 00821 Handler().LogError(this, "SendBuf", -1, "Attempt to write to a non-ready socket" ); // warning 00822 if (GetSocket() == INVALID_SOCKET) 00823 Handler().LogError(this, "SendBuf", 0, " * GetSocket() == INVALID_SOCKET", LOG_LEVEL_INFO); 00824 if (Connecting()) 00825 Handler().LogError(this, "SendBuf", 0, " * Connecting()", LOG_LEVEL_INFO); 00826 if (CloseAndDelete()) 00827 Handler().LogError(this, "SendBuf", 0, " * CloseAndDelete()", LOG_LEVEL_INFO); 00828 return; 00829 } 00830 if (!IsConnected()) 00831 { 00832 Handler().LogError(this, "SendBuf", -1, "Attempt to write to a non-connected socket, will be sent on connect" ); // warning 00833 Buffer(buf, len); 00834 return; 00835 } 00836 if (m_obuf_top) 00837 { 00838 Buffer(buf, len); 00839 return; 00840 } 00841 int n = TryWrite(buf, len); 00842 if (n > 0 && n < (int)len) 00843 { 00844 Buffer(buf + n, len - n); 00845 } 00846 // if ( data in buffer || !IsConnected ) 00847 // { 00848 // add to buffer 00849 // } 00850 // else 00851 // try_send 00852 // if any data is unsent, buffer it and set m_wfds 00853 00854 // check output buffer set, set/reset m_wfds accordingly 00855 { 00856 bool br; 00857 bool bw; 00858 bool bx; 00859 Handler().Get(GetSocket(), br, bw, bx); 00860 if (m_obuf.size()) 00861 Set(br, true); 00862 else 00863 Set(br, false); 00864 } 00865 }
void TcpSocket::OnRawData | ( | const char * | buf, | |
size_t | len | |||
) | [virtual] |
This callback is executed after a successful read from the socket.
buf | Pointer to the data | |
len | Length of the data |
Reimplemented in HTTPSocket.
Definition at line 1337 of file TcpSocket.cpp.
Referenced by OnRead().
void TcpSocket::OnWriteComplete | ( | ) | [virtual] |
Called when output buffer has been sent.
Definition at line 611 of file TcpSocket.cpp.
Referenced by OnWrite().
size_t TcpSocket::GetInputLength | ( | ) |
Number of bytes in input buffer.
Definition at line 1342 of file TcpSocket.cpp.
References TcpSocket::CircularBuffer::GetLength(), and ibuf.
Referenced by OnRead(), and OnSocks4Read().
size_t TcpSocket::GetOutputLength | ( | ) |
Number of bytes in output buffer.
Definition at line 1348 of file TcpSocket.cpp.
References m_output_length.
Referenced by OnWrite(), and SSLNegotiate().
01349 { 01350 return m_output_length; 01351 /* 01352 size_t len = 0; 01353 for (output_l::iterator it = m_obuf.begin(); it != m_obuf.end(); it++) 01354 len += (*it) -> Len(); 01355 return len; 01356 */ 01357 }
void TcpSocket::OnLine | ( | const std::string & | line | ) | [virtual] |
Callback fires when a socket in line protocol has read one full line.
line | Line read |
Reimplemented from Socket.
Reimplemented in HTTPSocket, ResolvSocket, and SmtpdSocket.
Definition at line 868 of file TcpSocket.cpp.
Referenced by OnRead().
uint64_t TcpSocket::GetBytesReceived | ( | bool | clear = false |
) | [virtual] |
Get counter of number of bytes received.
Reimplemented from Socket.
Definition at line 1360 of file TcpSocket.cpp.
References m_bytes_received.
01361 { 01362 uint64_t z = m_bytes_received; 01363 if (clear) 01364 m_bytes_received = 0; 01365 return z; 01366 }
uint64_t TcpSocket::GetBytesSent | ( | bool | clear = false |
) | [virtual] |
Get counter of number of bytes sent.
Reimplemented from Socket.
Definition at line 1369 of file TcpSocket.cpp.
References m_bytes_sent.
01370 { 01371 uint64_t z = m_bytes_sent; 01372 if (clear) 01373 m_bytes_sent = 0; 01374 return z; 01375 }
void TcpSocket::OnSocks4Connect | ( | ) | [virtual] |
Socks4 specific callback.
Reimplemented from Socket.
Definition at line 887 of file TcpSocket.cpp.
References Socket::GetClientRemoteAddress(), Socket::GetSocks4Userid(), m_socks4_state, and SendBuf().
00888 { 00889 char request[1000]; 00890 memset(request, 0, sizeof(request)); 00891 request[0] = 4; // socks v4 00892 request[1] = 1; // command code: CONNECT 00893 { 00894 std::auto_ptr<SocketAddress> ad = GetClientRemoteAddress(); 00895 if (ad.get()) 00896 { 00897 struct sockaddr *p0 = (struct sockaddr *)*ad; 00898 struct sockaddr_in *p = (struct sockaddr_in *)p0; 00899 if (p -> sin_family == AF_INET) 00900 { 00901 memcpy(request + 2, &p -> sin_port, 2); // nwbo is ok here 00902 memcpy(request + 4, &p -> sin_addr, sizeof(struct in_addr)); 00903 } 00904 else 00905 { 00907 } 00908 } 00909 else 00910 { 00912 } 00913 } 00914 strcpy(request + 8, GetSocks4Userid().c_str()); 00915 size_t length = GetSocks4Userid().size() + 8 + 1; 00916 SendBuf(request, length); 00917 m_socks4_state = 0; 00918 }
void TcpSocket::OnSocks4ConnectFailed | ( | ) | [virtual] |
Socks4 specific callback.
Reimplemented from Socket.
Definition at line 921 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().
00922 { 00923 Handler().LogError(this,"OnSocks4ConnectFailed",0,"connection to socks4 server failed, trying direct connection",LOG_LEVEL_WARNING); 00924 if (!Handler().Socks4TryDirect()) 00925 { 00926 SetConnecting(false); 00927 SetCloseAndDelete(); 00928 OnConnectFailed(); // just in case 00929 } 00930 else 00931 { 00932 SetRetryClientConnect(); 00933 } 00934 }
bool TcpSocket::OnSocks4Read | ( | ) | [virtual] |
Socks4 specific callback.
Reimplemented from Socket.
Definition at line 937 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().
00938 { 00939 switch (m_socks4_state) 00940 { 00941 case 0: 00942 ibuf.Read(&m_socks4_vn, 1); 00943 m_socks4_state = 1; 00944 break; 00945 case 1: 00946 ibuf.Read(&m_socks4_cd, 1); 00947 m_socks4_state = 2; 00948 break; 00949 case 2: 00950 if (GetInputLength() > 1) 00951 { 00952 ibuf.Read( (char *)&m_socks4_dstport, 2); 00953 m_socks4_state = 3; 00954 } 00955 else 00956 { 00957 return true; 00958 } 00959 break; 00960 case 3: 00961 if (GetInputLength() > 3) 00962 { 00963 ibuf.Read( (char *)&m_socks4_dstip, 4); 00964 SetSocks4(false); 00965 00966 switch (m_socks4_cd) 00967 { 00968 case 90: 00969 OnConnect(); 00970 Handler().LogError(this, "OnSocks4Read", 0, "Connection established", LOG_LEVEL_INFO); 00971 break; 00972 case 91: 00973 case 92: 00974 case 93: 00975 Handler().LogError(this,"OnSocks4Read",m_socks4_cd,"socks4 server reports connect failed",LOG_LEVEL_FATAL); 00976 SetConnecting(false); 00977 SetCloseAndDelete(); 00978 OnConnectFailed(); 00979 break; 00980 default: 00981 Handler().LogError(this,"OnSocks4Read",m_socks4_cd,"socks4 server unrecognized response",LOG_LEVEL_FATAL); 00982 SetCloseAndDelete(); 00983 break; 00984 } 00985 } 00986 else 00987 { 00988 return true; 00989 } 00990 break; 00991 } 00992 return false; 00993 }
Callback executed when resolver thread has finished a resolve request.
Reimplemented from Socket.
Definition at line 362 of file TcpSocket.cpp.
References ISocketHandler::Add(), Socket::Handler(), LOG_LEVEL_FATAL, ISocketHandler::LogError(), m_resolver_id, Open(), and Socket::SetCloseAndDelete().
Referenced by ResolvSocket::OnLine().
00363 { 00364 if (id == m_resolver_id) 00365 { 00366 if (a && port) 00367 { 00368 Ipv4Address ad(a, port); 00369 Ipv4Address local; 00370 if (Open(ad, local)) 00371 { 00372 if (!Handler().Valid(this)) 00373 { 00374 Handler().Add(this); 00375 } 00376 } 00377 } 00378 else 00379 { 00380 Handler().LogError(this, "OnResolved", 0, "Resolver failed", LOG_LEVEL_FATAL); 00381 SetCloseAndDelete(); 00382 } 00383 } 00384 else 00385 { 00386 Handler().LogError(this, "OnResolved", id, "Resolver returned wrong job id", LOG_LEVEL_FATAL); 00387 SetCloseAndDelete(); 00388 } 00389 }
void TcpSocket::OnSSLConnect | ( | ) | [virtual] |
Callback for 'New' ssl support - replaces SSLSocket.
Internal use.
Reimplemented from Socket.
Definition at line 1013 of file TcpSocket.cpp.
References DEB, Socket::GetSocket(), InitSSLClient(), m_sbio, m_ssl, m_ssl_ctx, Socket::SetCloseAndDelete(), Socket::SetNonblocking(), and Socket::SetSSLNegotiate().
01014 { 01015 SetNonblocking(true); 01016 { 01017 if (m_ssl_ctx) 01018 { 01019 DEB( fprintf(stderr, "SSL Context already initialized - closing socket\n");) 01020 SetCloseAndDelete(true); 01021 return; 01022 } 01023 InitSSLClient(); 01024 } 01025 if (m_ssl_ctx) 01026 { 01027 /* Connect the SSL socket */ 01028 m_ssl = SSL_new(m_ssl_ctx); 01029 if (!m_ssl) 01030 { 01031 DEB( fprintf(stderr, " m_ssl is NULL\n");) 01032 SetCloseAndDelete(true); 01033 return; 01034 } 01035 SSL_set_mode(m_ssl, SSL_MODE_AUTO_RETRY); 01036 m_sbio = BIO_new_socket((int)GetSocket(), BIO_NOCLOSE); 01037 if (!m_sbio) 01038 { 01039 DEB( fprintf(stderr, " m_sbio is NULL\n");) 01040 SetCloseAndDelete(true); 01041 return; 01042 } 01043 SSL_set_bio(m_ssl, m_sbio, m_sbio); 01044 // if (!SSLNegotiate()) 01045 { 01046 SetSSLNegotiate(); 01047 } 01048 } 01049 else 01050 { 01051 SetCloseAndDelete(); 01052 } 01053 }
void TcpSocket::OnSSLAccept | ( | ) | [virtual] |
Callback for 'New' ssl support - replaces SSLSocket.
Internal use.
Reimplemented from Socket.
Definition at line 1056 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().
01057 { 01058 SetNonblocking(true); 01059 { 01060 if (m_ssl_ctx) 01061 { 01062 DEB( fprintf(stderr, "SSL Context already initialized - closing socket\n");) 01063 SetCloseAndDelete(true); 01064 return; 01065 } 01066 InitSSLServer(); 01067 SetSSLServer(); 01068 } 01069 if (m_ssl_ctx) 01070 { 01071 m_ssl = SSL_new(m_ssl_ctx); 01072 if (!m_ssl) 01073 { 01074 DEB( fprintf(stderr, " m_ssl is NULL\n");) 01075 SetCloseAndDelete(true); 01076 return; 01077 } 01078 SSL_set_mode(m_ssl, SSL_MODE_AUTO_RETRY); 01079 m_sbio = BIO_new_socket((int)GetSocket(), BIO_NOCLOSE); 01080 if (!m_sbio) 01081 { 01082 DEB( fprintf(stderr, " m_sbio is NULL\n");) 01083 SetCloseAndDelete(true); 01084 return; 01085 } 01086 SSL_set_bio(m_ssl, m_sbio, m_sbio); 01087 // if (!SSLNegotiate()) 01088 { 01089 SetSSLNegotiate(); 01090 } 01091 } 01092 }
void TcpSocket::InitSSLClient | ( | ) | [virtual] |
This method must be implemented to initialize the ssl context for an outgoing connection.
Definition at line 1192 of file TcpSocket.cpp.
References InitializeContext().
Referenced by OnSSLConnect().
01193 { 01194 InitializeContext("", SSLv23_method()); 01195 }
void TcpSocket::InitSSLServer | ( | ) | [virtual] |
This method must be implemented to initialize the ssl context for an incoming connection.
Definition at line 1198 of file TcpSocket.cpp.
References Socket::Handler(), LOG_LEVEL_FATAL, ISocketHandler::LogError(), and Socket::SetCloseAndDelete().
Referenced by OnSSLAccept().
01199 { 01200 Handler().LogError(this, "InitSSLServer", 0, "You MUST implement your own InitSSLServer method", LOG_LEVEL_FATAL); 01201 SetCloseAndDelete(); 01202 }
void TcpSocket::SetReconnect | ( | bool | = true |
) |
Flag that says a broken connection will try to reconnect.
Definition at line 1330 of file TcpSocket.cpp.
References m_b_reconnect.
01331 { 01332 m_b_reconnect = x; 01333 }
bool TcpSocket::Reconnect | ( | ) |
Check reconnect on lost connection flag status.
Definition at line 1379 of file TcpSocket.cpp.
References m_b_reconnect.
Referenced by Open().
01380 { 01381 return m_b_reconnect; 01382 }
void TcpSocket::SetIsReconnect | ( | bool | x = true |
) |
Flag to determine if a reconnect is in progress.
Definition at line 1385 of file TcpSocket.cpp.
References m_b_is_reconnect.
01386 { 01387 m_b_is_reconnect = x; 01388 }
bool TcpSocket::IsReconnect | ( | ) |
Socket is reconnecting.
Definition at line 1391 of file TcpSocket.cpp.
References m_b_is_reconnect.
Referenced by SSLNegotiate().
01392 { 01393 return m_b_is_reconnect; 01394 }
void TcpSocket::DisableInputBuffer | ( | bool | = true |
) |
Definition at line 1406 of file TcpSocket.cpp.
References m_b_input_buffer_disabled.
Referenced by HTTPSocket::HTTPSocket(), and SetLineProtocol().
01407 { 01408 m_b_input_buffer_disabled = x; 01409 }
void TcpSocket::OnOptions | ( | int | family, | |
int | type, | |||
int | protocol, | |||
SOCKET | s | |||
) | [virtual] |
Called when a client socket is created, to set socket options.
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 1412 of file TcpSocket.cpp.
References DEB, Socket::SetSoKeepalive(), and Socket::SetSoReuseaddr().
01413 { 01414 DEB( fprintf(stderr, "Socket::OnOptions()\n");) 01415 #ifdef SO_NOSIGPIPE 01416 SetSoNosigpipe(true); 01417 #endif 01418 SetSoReuseaddr(true); 01419 SetSoKeepalive(true); 01420 }
void TcpSocket::SetLineProtocol | ( | bool | = true |
) | [virtual] |
Enable the OnLine callback.
Do not create your own OnRead callback when using this.
Reimplemented from StreamSocket.
Definition at line 1423 of file TcpSocket.cpp.
References DisableInputBuffer(), and StreamSocket::SetLineProtocol().
Referenced by HTTPSocket::HTTPSocket(), HTTPSocket::OnLine(), HTTPSocket::Reset(), ResolvSocket::ResolvSocket(), and SmtpdSocket::SmtpdSocket().
01424 { 01425 StreamSocket::SetLineProtocol(x); 01426 DisableInputBuffer(x); 01427 }
bool TcpSocket::SetTcpNodelay | ( | bool | = true |
) |
Definition at line 1430 of file TcpSocket.cpp.
References Errno, Socket::GetSocket(), Socket::Handler(), LOG_LEVEL_FATAL, LOG_LEVEL_INFO, ISocketHandler::LogError(), and StrError.
01431 { 01432 #ifdef TCP_NODELAY 01433 int optval = x ? 1 : 0; 01434 if (setsockopt(GetSocket(), IPPROTO_TCP, TCP_NODELAY, (char *)&optval, sizeof(optval)) == -1) 01435 { 01436 Handler().LogError(this, "setsockopt(IPPROTO_TCP, TCP_NODELAY)", Errno, StrError(Errno), LOG_LEVEL_FATAL); 01437 return false; 01438 } 01439 return true; 01440 #else 01441 Handler().LogError(this, "socket option not available", 0, "TCP_NODELAY", LOG_LEVEL_INFO); 01442 return false; 01443 #endif 01444 }
int TcpSocket::Protocol | ( | ) | [virtual] |
Returns IPPROTO_TCP or IPPROTO_SCTP.
Implements StreamSocket.
Definition at line 1661 of file TcpSocket.cpp.
void TcpSocket::SetTransferLimit | ( | size_t | sz | ) |
Trigger limit for callback OnTransferLimit.
Definition at line 1667 of file TcpSocket.cpp.
References m_transfer_limit.
01668 { 01669 m_transfer_limit = sz; 01670 }
void TcpSocket::OnTransferLimit | ( | ) | [virtual] |
This callback fires when the output buffer drops below the value set by SetTransferLimit.
Default: 0 (disabled).
Definition at line 1673 of file TcpSocket.cpp.
Referenced by OnWrite().
void TcpSocket::OnRead | ( | ) | [protected, virtual] |
Called when there is something to be read from the file descriptor.
Reimplemented from Socket.
Definition at line 420 of file TcpSocket.cpp.
References Socket::CloseAndDelete(), DEB, Errno, GetInputLength(), Socket::GetSocket(), Socket::GetTrafficMonitor(), Socket::Handler(), ibuf, Socket::IsSSL(), StreamSocket::LineProtocol(), LOG_LEVEL_ERROR, LOG_LEVEL_FATAL, LOG_LEVEL_WARNING, ISocketHandler::LogError(), m_b_input_buffer_disabled, m_buf, m_bytes_received, m_c, m_line, m_skip_c, m_ssl, Socket::OnDisconnect(), OnLine(), OnRawData(), OnSocks4Read(), StreamSocket::Ready(), Socket::SetCloseAndDelete(), StreamSocket::SetFlushBeforeClose(), Socket::SetLost(), StreamSocket::SetShutdown(), Socket::Socks4(), StrError, TCP_BUFSIZE_READ, and TcpSocket::CircularBuffer::Write().
00421 { 00422 int n = 0; 00423 #ifdef SOCKETS_DYNAMIC_TEMP 00424 char *buf = m_buf; 00425 #else 00426 char buf[TCP_BUFSIZE_READ]; 00427 #endif 00428 #ifdef HAVE_OPENSSL 00429 if (IsSSL()) 00430 { 00431 if (!Ready()) 00432 return; 00433 n = SSL_read(m_ssl, buf, TCP_BUFSIZE_READ); 00434 if (n == -1) 00435 { 00436 n = SSL_get_error(m_ssl, n); 00437 switch (n) 00438 { 00439 case SSL_ERROR_NONE: 00440 case SSL_ERROR_WANT_READ: 00441 case SSL_ERROR_WANT_WRITE: 00442 break; 00443 case SSL_ERROR_ZERO_RETURN: 00444 DEB( fprintf(stderr, "SSL_read() returns zero - closing socket\n");) 00445 SetCloseAndDelete(true); 00446 SetFlushBeforeClose(false); 00447 #ifdef ENABLE_POOL 00448 SetLost(); 00449 #endif 00450 break; 00451 default: 00452 DEB( fprintf(stderr, "SSL read problem, errcode = %d\n",n);) 00453 SetCloseAndDelete(true); 00454 SetFlushBeforeClose(false); 00455 #ifdef ENABLE_POOL 00456 SetLost(); 00457 #endif 00458 } 00459 return; 00460 } 00461 else 00462 if (!n) 00463 { 00464 OnDisconnect(); 00465 SetCloseAndDelete(true); 00466 SetFlushBeforeClose(false); 00467 #ifdef ENABLE_POOL 00468 SetLost(); 00469 #endif 00470 SetShutdown(SHUT_WR); 00471 return; 00472 } 00473 else 00474 if (n > 0 && n <= TCP_BUFSIZE_READ) 00475 { 00476 m_bytes_received += n; 00477 if (GetTrafficMonitor()) 00478 { 00479 GetTrafficMonitor() -> fwrite(buf, 1, n); 00480 } 00481 if (!m_b_input_buffer_disabled && !ibuf.Write(buf,n)) 00482 { 00483 Handler().LogError(this, "OnRead(ssl)", 0, "ibuf overflow", LOG_LEVEL_WARNING); 00484 } 00485 } 00486 else 00487 { 00488 Handler().LogError(this, "OnRead(ssl)", n, "abnormal value from SSL_read", LOG_LEVEL_ERROR); 00489 } 00490 } 00491 else 00492 #endif // HAVE_OPENSSL 00493 { 00494 n = recv(GetSocket(), buf, TCP_BUFSIZE_READ, MSG_NOSIGNAL); 00495 if (n == -1) 00496 { 00497 Handler().LogError(this, "read", Errno, StrError(Errno), LOG_LEVEL_FATAL); 00498 SetCloseAndDelete(true); 00499 SetFlushBeforeClose(false); 00500 #ifdef ENABLE_POOL 00501 SetLost(); 00502 #endif 00503 return; 00504 } 00505 else 00506 if (!n) 00507 { 00508 OnDisconnect(); 00509 SetCloseAndDelete(true); 00510 SetFlushBeforeClose(false); 00511 #ifdef ENABLE_POOL 00512 SetLost(); 00513 #endif 00514 SetShutdown(SHUT_WR); 00515 return; 00516 } 00517 else 00518 if (n > 0 && n <= TCP_BUFSIZE_READ) 00519 { 00520 m_bytes_received += n; 00521 if (GetTrafficMonitor()) 00522 { 00523 GetTrafficMonitor() -> fwrite(buf, 1, n); 00524 } 00525 if (!m_b_input_buffer_disabled && !ibuf.Write(buf,n)) 00526 { 00527 Handler().LogError(this, "OnRead", 0, "ibuf overflow", LOG_LEVEL_WARNING); 00528 } 00529 } 00530 else 00531 { 00532 Handler().LogError(this, "OnRead", n, "abnormal value from recv", LOG_LEVEL_ERROR); 00533 } 00534 } 00535 // unbuffered 00536 if (n > 0 && n <= TCP_BUFSIZE_READ) 00537 { 00538 if (LineProtocol()) 00539 { 00540 buf[n] = 0; 00541 int i = 0; 00542 if (m_skip_c && (buf[i] == 13 || buf[i] == 10) && buf[i] != m_c) 00543 { 00544 m_skip_c = false; 00545 i++; 00546 } 00547 size_t x = i; 00548 for (; i < n && LineProtocol(); i++) 00549 { 00550 while ((buf[i] == 13 || buf[i] == 10) && LineProtocol()) 00551 { 00552 char c = buf[i]; 00553 buf[i] = 0; 00554 if (buf[x]) 00555 { 00556 m_line += (buf + x); 00557 } 00558 OnLine( m_line ); 00559 i++; 00560 m_skip_c = true; 00561 m_c = c; 00562 if (i < n && (buf[i] == 13 || buf[i] == 10) && buf[i] != c) 00563 { 00564 m_skip_c = false; 00565 i++; 00566 } 00567 x = i; 00568 m_line = ""; 00569 } 00570 if (!LineProtocol()) 00571 { 00572 break; 00573 } 00574 } 00575 if (!LineProtocol()) 00576 { 00577 if (i < n) 00578 { 00579 OnRawData(buf + i, n - i); 00580 } 00581 } 00582 else 00583 if (buf[x]) 00584 { 00585 m_line += (buf + x); 00586 } 00587 } 00588 else 00589 { 00590 OnRawData(buf, n); 00591 } 00592 } 00593 if (m_b_input_buffer_disabled) 00594 { 00595 return; 00596 } 00597 // further processing: socks4 00598 #ifdef ENABLE_SOCKS4 00599 if (Socks4()) 00600 { 00601 bool need_more = false; 00602 while (GetInputLength() && !need_more && !CloseAndDelete()) 00603 { 00604 need_more = OnSocks4Read(); 00605 } 00606 } 00607 #endif 00608 }
void TcpSocket::OnWrite | ( | ) | [protected, virtual] |
Called when there is room for another write on the file descriptor.
Reimplemented from Socket.
Definition at line 616 of file TcpSocket.cpp.
References StreamSocket::Connecting(), ISocketHandler::Get(), StreamSocket::GetConnectionRetries(), StreamSocket::GetConnectionRetry(), GetOutputLength(), Socket::GetSocket(), Socket::Handler(), Socket::IsDisableRead(), LOG_LEVEL_FATAL, ISocketHandler::LogError(), m_obuf, m_obuf_top, m_output_length, m_transfer_limit, Socket::OnConnectFailed(), OnSocks4ConnectFailed(), OnTransferLimit(), OnWriteComplete(), Socket::Set(), StreamSocket::SetCallOnConnect(), Socket::SetCloseAndDelete(), StreamSocket::SetConnecting(), Socket::Socks4(), Socket::SoError(), StrError, and TryWrite().
Referenced by SSLNegotiate().
00617 { 00618 if (Connecting()) 00619 { 00620 int err = SoError(); 00621 00622 // don't reset connecting flag on error here, we want the OnConnectFailed timeout later on 00623 if (!err) // ok 00624 { 00625 Set(!IsDisableRead(), false); 00626 SetConnecting(false); 00627 SetCallOnConnect(); 00628 return; 00629 } 00630 Handler().LogError(this, "tcp: connect failed", err, StrError(err), LOG_LEVEL_FATAL); 00631 Set(false, false); // no more monitoring because connection failed 00632 00633 // failed 00634 #ifdef ENABLE_SOCKS4 00635 if (Socks4()) 00636 { 00637 // %! leave 'Connecting' flag set? 00638 OnSocks4ConnectFailed(); 00639 return; 00640 } 00641 #endif 00642 if (GetConnectionRetry() == -1 || 00643 (GetConnectionRetry() && GetConnectionRetries() < GetConnectionRetry()) ) 00644 { 00645 // even though the connection failed at once, only retry after 00646 // the connection timeout. 00647 // should we even try to connect again, when CheckConnect returns 00648 // false it's because of a connection error - not a timeout... 00649 return; 00650 } 00651 SetConnecting(false); 00652 SetCloseAndDelete( true ); 00654 OnConnectFailed(); 00655 return; 00656 } 00657 // try send next block in buffer 00658 // if full block is sent, repeat 00659 // if all blocks are sent, reset m_wfds 00660 00661 bool repeat = false; 00662 size_t sz = m_transfer_limit ? GetOutputLength() : 0; 00663 do 00664 { 00665 output_l::iterator it = m_obuf.begin(); 00666 OUTPUT *p = *it; 00667 repeat = false; 00668 int n = TryWrite(p -> Buf(), p -> Len()); 00669 if (n > 0) 00670 { 00671 size_t left = p -> Remove(n); 00672 m_output_length -= n; 00673 if (!left) 00674 { 00675 delete p; 00676 m_obuf.erase(it); 00677 if (!m_obuf.size()) 00678 { 00679 m_obuf_top = NULL; 00680 OnWriteComplete(); 00681 } 00682 else 00683 { 00684 repeat = true; 00685 } 00686 } 00687 } 00688 } while (repeat); 00689 00690 if (m_transfer_limit && sz > m_transfer_limit && GetOutputLength() < m_transfer_limit) 00691 { 00692 OnTransferLimit(); 00693 } 00694 00695 // check output buffer set, set/reset m_wfds accordingly 00696 { 00697 bool br; 00698 bool bw; 00699 bool bx; 00700 Handler().Get(GetSocket(), br, bw, bx); 00701 if (m_obuf.size()) 00702 Set(br, true); 00703 else 00704 Set(br, false); 00705 } 00706 }
void TcpSocket::InitializeContext | ( | const std::string & | context, | |
SSL_METHOD * | meth_in = NULL | |||
) | [protected] |
SSL; Initialize ssl context for a client socket.
meth_in | SSL method |
Definition at line 1205 of file TcpSocket.cpp.
References m_ssl_ctx.
Referenced by InitSSLClient().
01206 { 01207 /* Create our context*/ 01208 static std::map<std::string, SSL_CTX *> client_contexts; 01209 if (client_contexts.find(context) == client_contexts.end()) 01210 { 01211 SSL_METHOD *meth = meth_in ? meth_in : SSLv3_method(); 01212 m_ssl_ctx = client_contexts[context] = SSL_CTX_new(meth); 01213 SSL_CTX_set_mode(m_ssl_ctx, SSL_MODE_AUTO_RETRY); 01214 } 01215 else 01216 { 01217 m_ssl_ctx = client_contexts[context]; 01218 } 01219 }
void TcpSocket::InitializeContext | ( | const std::string & | context, | |
const std::string & | keyfile, | |||
const std::string & | password, | |||
SSL_METHOD * | meth_in = NULL | |||
) | [protected] |
SSL; Initialize ssl context for a server socket.
keyfile | Combined private key/certificate file | |
password | Password for private key | |
meth_in | SSL method |
Definition at line 1222 of file TcpSocket.cpp.
References Socket::Handler(), LOG_LEVEL_FATAL, ISocketHandler::LogError(), m_password, m_ssl_ctx, and SSL_password_cb().
01223 { 01224 /* Create our context*/ 01225 static std::map<std::string, SSL_CTX *> server_contexts; 01226 if (server_contexts.find(context) == server_contexts.end()) 01227 { 01228 SSL_METHOD *meth = meth_in ? meth_in : SSLv3_method(); 01229 m_ssl_ctx = server_contexts[context] = SSL_CTX_new(meth); 01230 SSL_CTX_set_mode(m_ssl_ctx, SSL_MODE_AUTO_RETRY); 01231 // session id 01232 if (context.size()) 01233 SSL_CTX_set_session_id_context(m_ssl_ctx, (const unsigned char *)context.c_str(), (unsigned int)context.size()); 01234 else 01235 SSL_CTX_set_session_id_context(m_ssl_ctx, (const unsigned char *)"--empty--", 9); 01236 } 01237 else 01238 { 01239 m_ssl_ctx = server_contexts[context]; 01240 } 01241 01242 /* Load our keys and certificates*/ 01243 if (!(SSL_CTX_use_certificate_file(m_ssl_ctx, keyfile.c_str(), SSL_FILETYPE_PEM))) 01244 { 01245 Handler().LogError(this, "TcpSocket InitializeContext", 0, "Couldn't read certificate file " + keyfile, LOG_LEVEL_FATAL); 01246 } 01247 01248 m_password = password; 01249 SSL_CTX_set_default_passwd_cb(m_ssl_ctx, SSL_password_cb); 01250 SSL_CTX_set_default_passwd_cb_userdata(m_ssl_ctx, this); 01251 if (!(SSL_CTX_use_PrivateKey_file(m_ssl_ctx, keyfile.c_str(), SSL_FILETYPE_PEM))) 01252 { 01253 Handler().LogError(this, "TcpSocket InitializeContext", 0, "Couldn't read private key file " + keyfile, LOG_LEVEL_FATAL); 01254 } 01255 }
int TcpSocket::SSL_password_cb | ( | char * | buf, | |
int | num, | |||
int | rwflag, | |||
void * | userdata | |||
) | [static, protected] |
SSL; Password callback method.
Definition at line 1258 of file TcpSocket.cpp.
References GetPassword().
Referenced by InitializeContext().
01259 { 01260 Socket *p0 = static_cast<Socket *>(userdata); 01261 TcpSocket *p = dynamic_cast<TcpSocket *>(p0); 01262 std::string pw = p ? p -> GetPassword() : ""; 01263 if ( (size_t)num < pw.size() + 1) 01264 { 01265 return 0; 01266 } 01267 strcpy(buf,pw.c_str()); 01268 return (int)pw.size(); 01269 }
SSL_CTX * TcpSocket::GetSslContext | ( | ) | [protected, virtual] |
SSL; Get pointer to ssl context structure.
Reimplemented from Socket.
Definition at line 1313 of file TcpSocket.cpp.
References Socket::Handler(), LOG_LEVEL_WARNING, ISocketHandler::LogError(), and m_ssl_ctx.
01314 { 01315 if (!m_ssl_ctx) 01316 Handler().LogError(this, "GetSslContext", 0, "SSL Context is NULL; check InitSSLServer/InitSSLClient", LOG_LEVEL_WARNING); 01317 return m_ssl_ctx; 01318 }
SSL * TcpSocket::GetSsl | ( | ) | [protected, virtual] |
SSL; Get pointer to ssl structure.
Reimplemented from Socket.
Definition at line 1320 of file TcpSocket.cpp.
References Socket::Handler(), LOG_LEVEL_WARNING, ISocketHandler::LogError(), and m_ssl.
01321 { 01322 if (!m_ssl) 01323 Handler().LogError(this, "GetSsl", 0, "SSL is NULL; check InitSSLServer/InitSSLClient", LOG_LEVEL_WARNING); 01324 return m_ssl; 01325 }
bool TcpSocket::SSLNegotiate | ( | ) | [protected, virtual] |
ssl; still negotiating connection.
Reimplemented from Socket.
Definition at line 1095 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(), Socket::SetNonblocking(), and Socket::SetSSLNegotiate().
01096 { 01097 if (!IsSSLServer()) // client 01098 { 01099 int r = SSL_connect(m_ssl); 01100 if (r > 0) 01101 { 01102 SetSSLNegotiate(false); 01104 // CheckCertificateChain( "");//ServerHOST); 01105 SetNonblocking(false); 01106 // 01107 { 01108 SetConnected(); 01109 if (GetOutputLength()) 01110 { 01111 OnWrite(); 01112 } 01113 } 01114 #ifdef ENABLE_RECONNECT 01115 if (IsReconnect()) 01116 OnReconnect(); 01117 else 01118 #endif 01119 { 01120 OnConnect(); 01121 } 01122 Handler().LogError(this, "SSLNegotiate/SSL_connect", 0, "Connection established", LOG_LEVEL_INFO); 01123 return true; 01124 } 01125 else 01126 if (!r) 01127 { 01128 Handler().LogError(this, "SSLNegotiate/SSL_connect", 0, "Connection failed", LOG_LEVEL_INFO); 01129 SetSSLNegotiate(false); 01130 SetCloseAndDelete(); 01131 OnSSLConnectFailed(); 01132 } 01133 else 01134 { 01135 r = SSL_get_error(m_ssl, r); 01136 if (r != SSL_ERROR_WANT_READ && r != SSL_ERROR_WANT_WRITE) 01137 { 01138 Handler().LogError(this, "SSLNegotiate/SSL_connect", -1, "Connection failed", LOG_LEVEL_INFO); 01139 DEB( fprintf(stderr, "SSL_connect() failed - closing socket, return code: %d\n",r);) 01140 SetSSLNegotiate(false); 01141 SetCloseAndDelete(true); 01142 OnSSLConnectFailed(); 01143 } 01144 } 01145 } 01146 else // server 01147 { 01148 int r = SSL_accept(m_ssl); 01149 if (r > 0) 01150 { 01151 SetSSLNegotiate(false); 01153 // CheckCertificateChain( "");//ClientHOST); 01154 SetNonblocking(false); 01155 // 01156 { 01157 SetConnected(); 01158 if (GetOutputLength()) 01159 { 01160 OnWrite(); 01161 } 01162 } 01163 OnAccept(); 01164 Handler().LogError(this, "SSLNegotiate/SSL_accept", 0, "Connection established", LOG_LEVEL_INFO); 01165 return true; 01166 } 01167 else 01168 if (!r) 01169 { 01170 Handler().LogError(this, "SSLNegotiate/SSL_accept", 0, "Connection failed", LOG_LEVEL_INFO); 01171 SetSSLNegotiate(false); 01172 SetCloseAndDelete(); 01173 OnSSLAcceptFailed(); 01174 } 01175 else 01176 { 01177 r = SSL_get_error(m_ssl, r); 01178 if (r != SSL_ERROR_WANT_READ && r != SSL_ERROR_WANT_WRITE) 01179 { 01180 Handler().LogError(this, "SSLNegotiate/SSL_accept", -1, "Connection failed", LOG_LEVEL_INFO); 01181 DEB( fprintf(stderr, "SSL_accept() failed - closing socket, return code: %d\n",r);) 01182 SetSSLNegotiate(false); 01183 SetCloseAndDelete(true); 01184 OnSSLAcceptFailed(); 01185 } 01186 } 01187 } 01188 return false; 01189 }
const std::string & TcpSocket::GetPassword | ( | ) | [protected] |
SSL; Get ssl password.
Definition at line 1399 of file TcpSocket.cpp.
References m_password.
Referenced by SSL_password_cb().
01400 { 01401 return m_password; 01402 }
int TcpSocket::TryWrite | ( | const char * | buf, | |
size_t | len | |||
) | [private] |
the actual send()
Definition at line 709 of file TcpSocket.cpp.
References DEB, Errno, Socket::GetSocket(), Socket::GetTrafficMonitor(), Socket::Handler(), Socket::IsSSL(), LOG_LEVEL_FATAL, ISocketHandler::LogError(), m_bytes_sent, m_ssl, Socket::SetCloseAndDelete(), StreamSocket::SetFlushBeforeClose(), Socket::SetLost(), and StrError.
Referenced by OnWrite(), and SendBuf().
00710 { 00711 int n = 0; 00712 #ifdef HAVE_OPENSSL 00713 if (IsSSL()) 00714 { 00715 n = SSL_write(m_ssl, buf, len); 00716 if (n == -1) 00717 { 00718 int errnr = SSL_get_error(m_ssl, n); 00719 if ( errnr != SSL_ERROR_WANT_READ && errnr != SSL_ERROR_WANT_WRITE ) 00720 { 00721 SetCloseAndDelete(true); 00722 SetFlushBeforeClose(false); 00723 #ifdef ENABLE_POOL 00724 SetLost(); 00725 #endif 00726 const char *errbuf = ERR_error_string(errnr, NULL); 00727 Handler().LogError(this, "OnWrite/SSL_write", errnr, errbuf, LOG_LEVEL_FATAL); 00728 } 00729 } 00730 else 00731 if (!n) 00732 { 00733 SetCloseAndDelete(true); 00734 SetFlushBeforeClose(false); 00735 #ifdef ENABLE_POOL 00736 SetLost(); 00737 #endif 00738 DEB( int errnr = SSL_get_error(m_ssl, n); 00739 const char *errbuf = ERR_error_string(errnr, NULL); 00740 fprintf(stderr, "SSL_write() returns 0: %d : %s\n",errnr, errbuf);) 00741 } 00742 } 00743 else 00744 #endif // HAVE_OPENSSL 00745 { 00746 n = send(GetSocket(), buf, len, MSG_NOSIGNAL); 00747 if (n == -1) 00748 { 00749 // normal error codes: 00750 // WSAEWOULDBLOCK 00751 // EAGAIN or EWOULDBLOCK 00752 #ifdef _WIN32 00753 if (Errno != WSAEWOULDBLOCK) 00754 #else 00755 if (Errno != EWOULDBLOCK) 00756 #endif 00757 { 00758 Handler().LogError(this, "send", Errno, StrError(Errno), LOG_LEVEL_FATAL); 00759 SetCloseAndDelete(true); 00760 SetFlushBeforeClose(false); 00761 #ifdef ENABLE_POOL 00762 SetLost(); 00763 #endif 00764 } 00765 } 00766 } 00767 if (n > 0) 00768 { 00769 m_bytes_sent += n; 00770 if (GetTrafficMonitor()) 00771 { 00772 GetTrafficMonitor() -> fwrite(buf, 1, n); 00773 } 00774 } 00775 return n; 00776 }
void TcpSocket::Buffer | ( | const char * | buf, | |
size_t | len | |||
) | [private] |
add data to output buffer top
Definition at line 779 of file TcpSocket.cpp.
References m_obuf, m_obuf_top, and m_output_length.
Referenced by SendBuf().
00780 { 00781 size_t ptr = 0; 00782 m_output_length += len; 00783 while (ptr < len) 00784 { 00785 // buf/len => pbuf/sz 00786 size_t space = 0; 00787 if (m_obuf_top && (space = m_obuf_top -> Space()) > 0) 00788 { 00789 const char *pbuf = buf + ptr; 00790 size_t sz = len - ptr; 00791 if (space >= sz) 00792 { 00793 m_obuf_top -> Add(pbuf, sz); 00794 ptr += sz; 00795 } 00796 else 00797 { 00798 m_obuf_top -> Add(pbuf, space); 00799 ptr += space; 00800 } 00801 } 00802 else 00803 { 00804 m_obuf_top = new OUTPUT; 00805 m_obuf.push_back( m_obuf_top ); 00806 } 00807 } 00808 }
CircularBuffer TcpSocket::ibuf [protected] |
Circular input buffer.
Definition at line 287 of file TcpSocket.h.
Referenced by GetInputLength(), OnRead(), and OnSocks4Read().
bool TcpSocket::m_b_input_buffer_disabled [private] |
uint64_t TcpSocket::m_bytes_sent [private] |
uint64_t TcpSocket::m_bytes_received [private] |
bool TcpSocket::m_skip_c [private] |
Skip second char of CRLF or LFCR sequence in OnRead.
Definition at line 301 of file TcpSocket.h.
Referenced by OnRead().
char TcpSocket::m_c [private] |
First char in CRLF or LFCR sequence.
Definition at line 302 of file TcpSocket.h.
Referenced by OnRead().
std::string TcpSocket::m_line [private] |
Current line in line protocol mode.
Reimplemented in HTTPSocket.
Definition at line 303 of file TcpSocket.h.
Referenced by OnRead().
char* TcpSocket::m_buf [private] |
temporary read buffer
Definition at line 305 of file TcpSocket.h.
Referenced by OnRead(), and ~TcpSocket().
output_l TcpSocket::m_obuf [private] |
OUTPUT* TcpSocket::m_obuf_top [private] |
size_t TcpSocket::m_transfer_limit [private] |
size_t TcpSocket::m_output_length [private] |
Definition at line 310 of file TcpSocket.h.
Referenced by Buffer(), GetOutputLength(), and OnWrite().
SSLInitializer TcpSocket::m_ssl_init [static, private] |
Definition at line 313 of file TcpSocket.h.
SSL_CTX* TcpSocket::m_ssl_ctx [private] |
ssl context
Definition at line 314 of file TcpSocket.h.
Referenced by GetSslContext(), InitializeContext(), OnSSLAccept(), and OnSSLConnect().
SSL* TcpSocket::m_ssl [private] |
ssl 'socket'
Definition at line 315 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 316 of file TcpSocket.h.
Referenced by OnSSLAccept(), and OnSSLConnect().
std::string TcpSocket::m_password [private] |
ssl password
Definition at line 317 of file TcpSocket.h.
Referenced by GetPassword(), and InitializeContext().
int TcpSocket::m_socks4_state [private] |
socks4 support
Definition at line 321 of file TcpSocket.h.
Referenced by OnSocks4Connect(), and OnSocks4Read().
char TcpSocket::m_socks4_vn [private] |
socks4 support, temporary variable
Definition at line 322 of file TcpSocket.h.
Referenced by OnSocks4Read().
char TcpSocket::m_socks4_cd [private] |
socks4 support, temporary variable
Definition at line 323 of file TcpSocket.h.
Referenced by OnSocks4Read().
unsigned short TcpSocket::m_socks4_dstport [private] |
unsigned long TcpSocket::m_socks4_dstip [private] |
int TcpSocket::m_resolver_id [private] |
Resolver id (if any) for current Open call.
Definition at line 329 of file TcpSocket.h.
Referenced by OnResolved(), and Open().
bool TcpSocket::m_b_reconnect [private] |
Reconnect on lost connection flag.
Definition at line 333 of file TcpSocket.h.
Referenced by Reconnect(), and SetReconnect().
bool TcpSocket::m_b_is_reconnect [private] |
Trying to reconnect.
Definition at line 334 of file TcpSocket.h.
Referenced by IsReconnect(), and SetIsReconnect().