![]() |
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 | ReadInput (char *buf, size_t sz) |
Read from input buffer. | |
size_t | GetOutputLength () |
Number of bytes in output buffer. | |
void | OnLine (const std::string &line) |
Callback fires when a socket in line protocol has read one full line. | |
uint64_t | GetBytesReceived (bool clear=false) |
Get counter of number of bytes received. | |
uint64_t | GetBytesSent (bool clear=false) |
Get counter of number of bytes sent. | |
void | OnSocks4Connect () |
Socks4 specific callback. | |
void | OnSocks4ConnectFailed () |
Socks4 specific callback. | |
bool | OnSocks4Read () |
Socks4 specific callback. | |
void | OnResolved (int id, ipaddr_t a, port_t port) |
Callback executed when resolver thread has finished a resolve request. | |
void | OnSSLConnect () |
Callback for 'New' ssl support - replaces SSLSocket. | |
void | OnSSLAccept () |
Callback for 'New' ssl support - replaces SSLSocket. | |
virtual void | InitSSLClient () |
This method must be implemented to initialize the ssl context for an outgoing connection. | |
virtual void | InitSSLServer () |
This method must be implemented to initialize the ssl context for an incoming connection. | |
void | SetReconnect (bool=true) |
Flag that says a broken connection will try to reconnect. | |
bool | Reconnect () |
Check reconnect on lost connection flag status. | |
void | SetIsReconnect (bool x=true) |
Flag to determine if a reconnect is in progress. | |
bool | IsReconnect () |
Socket is reconnecting. | |
void | DisableInputBuffer (bool=true) |
Use this if you only use OnRawData to process received data. | |
void | OnOptions (int, int, int, SOCKET) |
Called when a client socket is created, to set socket options. | |
void | SetLineProtocol (bool=true) |
Called after OnRead if socket is in line protocol mode. | |
const std::string | GetLine () const |
Get the unfinished line when using SetLineProtocol = true. | |
bool | SetTcpNodelay (bool=true) |
virtual int | Protocol () |
Returns IPPROTO_TCP or IPPROTO_SCTP. | |
void | SetTransferLimit (size_t sz) |
Trigger limit for callback OnTransferLimit. | |
virtual void | OnTransferLimit () |
This callback fires when the output buffer drops below the value set by SetTransferLimit. | |
Protected Types | |
typedef std::list< OUTPUT * > | output_l |
Protected Member Functions | |
TcpSocket (const TcpSocket &) | |
void | OnRead () |
Called when there is something to be read from the file descriptor. | |
void | OnRead (char *buf, size_t n) |
void | OnWrite () |
Called when there is room for another write on the file descriptor. | |
void | InitializeContext (const std::string &context, const SSL_METHOD *meth_in=NULL) |
SSL; Initialize ssl context for a client socket. | |
void | InitializeContext (const std::string &context, const std::string &keyfile, const std::string &password, const SSL_METHOD *meth_in=NULL) |
SSL; Initialize ssl context for a server socket. | |
void | InitializeContext (const std::string &context, const std::string &certfile, const std::string &keyfile, const std::string &password, const SSL_METHOD *meth_in=NULL) |
SSL; Initialize ssl context for a server socket. | |
void | UseCertificateChainFile (const std::string &filename) |
SSL; load certificate chain from file. | |
virtual SSL_CTX * | GetSslContext () |
SSL; Get pointer to ssl context structure. | |
virtual SSL * | GetSsl () |
SSL; Get pointer to ssl structure. | |
bool | SSLNegotiate () |
ssl; still negotiating connection. | |
const std::string & | GetPassword () |
SSL; Get ssl password. | |
Static Protected Member Functions | |
static int | SSL_password_cb (char *buf, int num, int rwflag, void *userdata) |
SSL; Password callback method. | |
Protected Attributes | |
CircularBuffer | ibuf |
Circular input buffer. | |
Private Member Functions | |
TcpSocket & | operator= (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 | |
OUTPUT * | m_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... |
Definition at line 62 of file TcpSocket.h.
typedef std::list<OUTPUT *> TcpSocket::output_l [protected] |
Definition at line 121 of file TcpSocket.h.
TcpSocket::TcpSocket | ( | ISocketHandler & | h | ) |
Constructor with standard values on input/output buffers.
Definition at line 86 of file TcpSocket.cpp.
00086 : StreamSocket(h) 00087 ,ibuf(TCP_BUFSIZE_READ) 00088 ,m_b_input_buffer_disabled(false) 00089 ,m_bytes_sent(0) 00090 ,m_bytes_received(0) 00091 ,m_skip_c(false) 00092 ,m_line(Handler().MaxTcpLineSize()) 00093 ,m_line_ptr(0) 00094 #ifdef SOCKETS_DYNAMIC_TEMP 00095 ,m_buf(new char[TCP_BUFSIZE_READ + 1]) 00096 #endif 00097 ,m_obuf_top(NULL) 00098 ,m_transfer_limit(0) 00099 ,m_output_length(0) 00100 ,m_repeat_length(0) 00101 #ifdef HAVE_OPENSSL 00102 ,m_ssl_ctx(NULL) 00103 ,m_ssl(NULL) 00104 ,m_sbio(NULL) 00105 #endif 00106 #ifdef ENABLE_SOCKS4 00107 ,m_socks4_state(0) 00108 #endif 00109 #ifdef ENABLE_RESOLVER 00110 ,m_resolver_id(0) 00111 #endif 00112 #ifdef ENABLE_RECONNECT 00113 ,m_b_reconnect(false) 00114 ,m_b_is_reconnect(false) 00115 #endif 00116 { 00117 }
TcpSocket::TcpSocket | ( | ISocketHandler & | h, | |
size_t | isize, | |||
size_t | osize | |||
) |
Constructor with custom values for i/o buffer.
h | ISocketHandler reference | |
isize | Input buffer size | |
osize | Output buffer size |
Definition at line 126 of file TcpSocket.cpp.
00126 : StreamSocket(h) 00127 ,ibuf(isize) 00128 ,m_b_input_buffer_disabled(false) 00129 ,m_bytes_sent(0) 00130 ,m_bytes_received(0) 00131 ,m_skip_c(false) 00132 ,m_line(Handler().MaxTcpLineSize()) 00133 ,m_line_ptr(0) 00134 #ifdef SOCKETS_DYNAMIC_TEMP 00135 ,m_buf(new char[TCP_BUFSIZE_READ + 1]) 00136 #endif 00137 ,m_obuf_top(NULL) 00138 ,m_transfer_limit(0) 00139 ,m_output_length(0) 00140 ,m_repeat_length(0) 00141 #ifdef HAVE_OPENSSL 00142 ,m_ssl_ctx(NULL) 00143 ,m_ssl(NULL) 00144 ,m_sbio(NULL) 00145 #endif 00146 #ifdef ENABLE_SOCKS4 00147 ,m_socks4_state(0) 00148 #endif 00149 #ifdef ENABLE_RESOLVER 00150 ,m_resolver_id(0) 00151 #endif 00152 #ifdef ENABLE_RECONNECT 00153 ,m_b_reconnect(false) 00154 ,m_b_is_reconnect(false) 00155 #endif 00156 { 00157 }
TcpSocket::~TcpSocket | ( | ) |
Definition at line 163 of file TcpSocket.cpp.
References m_buf, m_obuf, and m_ssl.
00164 { 00165 #ifdef SOCKETS_DYNAMIC_TEMP 00166 delete[] m_buf; 00167 #endif 00168 // %! empty m_obuf 00169 while (m_obuf.size()) 00170 { 00171 output_l::iterator it = m_obuf.begin(); 00172 OUTPUT *p = *it; 00173 delete p; 00174 m_obuf.erase(it); 00175 } 00176 #ifdef HAVE_OPENSSL 00177 if (m_ssl) 00178 { 00179 SSL_free(m_ssl); 00180 } 00181 #endif 00182 }
TcpSocket::TcpSocket | ( | const TcpSocket & | s | ) | [protected] |
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 185 of file TcpSocket.cpp.
Referenced by HttpGetSocket::DoConnect(), OnResolved(), Open(), HttpPutSocket::Open(), and HttpPostSocket::Open().
00186 { 00187 Ipv4Address ad(ip, port); 00188 Ipv4Address local; 00189 return Open(ad, local, skip_socks); 00190 }
bool TcpSocket::Open | ( | SocketAddress & | ad, | |
bool | skip_socks = false | |||
) |
Definition at line 204 of file TcpSocket.cpp.
References Open().
00205 { 00206 Ipv4Address bind_ad("0.0.0.0", 0); 00207 return Open(ad, bind_ad, skip_socks); 00208 }
bool TcpSocket::Open | ( | SocketAddress & | ad, | |
SocketAddress & | bind_address, | |||
bool | skip_socks = false | |||
) |
Definition at line 211 of file TcpSocket.cpp.
References Socket::Attach(), closesocket, Socket::CopyConnection(), Socket::CreateSocket(), Errno, ISocketHandler::FindConnection(), SocketAddress::GetFamily(), SocketAddress::GetPort(), Socket::GetSocks4Host(), Socket::GetSocks4Port(), Socket::Handler(), INVALID_SOCKET, SocketAddress::IsValid(), Utility::l2ip(), Utility::l2string(), LOG_LEVEL_FATAL, LOG_LEVEL_INFO, ISocketHandler::LogError(), Open(), Reconnect(), Socket::SetCallOnConnect(), Socket::SetClientRemoteAddress(), Socket::SetCloseAndDelete(), StreamSocket::SetConnecting(), Socket::SetIsClient(), Socket::SetNonblocking(), Socket::SetRemoteAddress(), Socket::SetSocks4(), Socket::Socks4(), and StrError.
00212 { 00213 if (!ad.IsValid()) 00214 { 00215 Handler().LogError(this, "Open", 0, "Invalid SocketAddress", LOG_LEVEL_FATAL); 00216 SetCloseAndDelete(); 00217 return false; 00218 } 00219 if (Handler().GetCount() >= Handler().MaxCount()) 00220 { 00221 Handler().LogError(this, "Open", 0, "no space left for more sockets", LOG_LEVEL_FATAL); 00222 SetCloseAndDelete(); 00223 return false; 00224 } 00225 SetConnecting(false); 00226 #ifdef ENABLE_SOCKS4 00227 SetSocks4(false); 00228 #endif 00229 // check for pooling 00230 #ifdef ENABLE_POOL 00231 if (Handler().PoolEnabled()) 00232 { 00233 ISocketHandler::PoolSocket *pools = Handler().FindConnection(SOCK_STREAM, "tcp", ad); 00234 if (pools) 00235 { 00236 CopyConnection( pools ); 00237 delete pools; 00238 00239 SetIsClient(); 00240 SetCallOnConnect(); // ISocketHandler must call OnConnect 00241 Handler().LogError(this, "SetCallOnConnect", 0, "Found pooled connection", LOG_LEVEL_INFO); 00242 return true; 00243 } 00244 } 00245 #endif 00246 // if not, create new connection 00247 SOCKET s = CreateSocket(ad.GetFamily(), SOCK_STREAM, "tcp"); 00248 if (s == INVALID_SOCKET) 00249 { 00250 return false; 00251 } 00252 // socket must be nonblocking for async connect 00253 if (!SetNonblocking(true, s)) 00254 { 00255 SetCloseAndDelete(); 00256 closesocket(s); 00257 return false; 00258 } 00259 #ifdef ENABLE_POOL 00260 SetIsClient(); // client because we connect 00261 #endif 00262 SetClientRemoteAddress(ad); 00263 int n = 0; 00264 if (bind_ad.GetPort() != 0) 00265 { 00266 bind(s, bind_ad, bind_ad); 00267 } 00268 #ifdef ENABLE_SOCKS4 00269 if (!skip_socks && GetSocks4Host() && GetSocks4Port()) 00270 { 00271 Ipv4Address sa(GetSocks4Host(), GetSocks4Port()); 00272 { 00273 std::string sockshost; 00274 Utility::l2ip(GetSocks4Host(), sockshost); 00275 Handler().LogError(this, "Open", 0, "Connecting to socks4 server @ " + sockshost + ":" + 00276 Utility::l2string(GetSocks4Port()), LOG_LEVEL_INFO); 00277 } 00278 SetSocks4(); 00279 n = connect(s, sa, sa); 00280 SetRemoteAddress(sa); 00281 } 00282 else 00283 #endif 00284 { 00285 n = connect(s, ad, ad); 00286 SetRemoteAddress(ad); 00287 } 00288 if (n == -1) 00289 { 00290 // check error code that means a connect is in progress 00291 #ifdef _WIN32 00292 if (Errno == WSAEWOULDBLOCK) 00293 #else 00294 if (Errno == EINPROGRESS) 00295 #endif 00296 { 00297 Attach(s); 00298 SetConnecting( true ); // this flag will control fd_set's 00299 } 00300 else 00301 #ifdef ENABLE_SOCKS4 00302 if (Socks4() && Handler().Socks4TryDirect() ) // retry 00303 { 00304 closesocket(s); 00305 return Open(ad, true); 00306 } 00307 else 00308 #endif 00309 #ifdef ENABLE_RECONNECT 00310 if (Reconnect()) 00311 { 00312 Handler().LogError(this, "connect: failed, reconnect pending", Errno, StrError(Errno), LOG_LEVEL_INFO); 00313 Attach(s); 00314 SetConnecting( true ); // this flag will control fd_set's 00315 } 00316 else 00317 #endif 00318 { 00319 Handler().LogError(this, "connect: failed", Errno, StrError(Errno), LOG_LEVEL_FATAL); 00320 SetCloseAndDelete(); 00321 closesocket(s); 00322 return false; 00323 } 00324 } 00325 else 00326 { 00327 Attach(s); 00328 SetCallOnConnect(); // ISocketHandler must call OnConnect 00329 } 00330 00331 // 'true' means connected or connecting(not yet connected) 00332 // 'false' means something failed 00333 return true; 00334 }
bool TcpSocket::Open | ( | const std::string & | host, | |
port_t | port | |||
) |
Open connection.
host | Hostname | |
port | Port number |
Definition at line 337 of file TcpSocket.cpp.
References Socket::Handler(), Utility::isipv4(), Utility::isipv6(), m_resolver_id, Open(), Socket::Resolve(), Socket::SetCloseAndDelete(), and Utility::u2ip().
00338 { 00339 #ifdef ENABLE_IPV6 00340 #ifdef IPPROTO_IPV6 00341 if (IsIpv6()) 00342 { 00343 #ifdef ENABLE_RESOLVER 00344 if (!Handler().ResolverEnabled() || Utility::isipv6(host) ) 00345 { 00346 #endif 00347 in6_addr a; 00348 if (!Utility::u2ip(host, a)) 00349 { 00350 SetCloseAndDelete(); 00351 return false; 00352 } 00353 Ipv6Address ad(a, port); 00354 Ipv6Address local; 00355 return Open(ad, local); 00356 #ifdef ENABLE_RESOLVER 00357 } 00358 m_resolver_id = Resolve6(host, port); 00359 return true; 00360 #endif 00361 } 00362 #endif 00363 #endif 00364 #ifdef ENABLE_RESOLVER 00365 if (!Handler().ResolverEnabled() || Utility::isipv4(host) ) 00366 { 00367 #endif 00368 ipaddr_t l; 00369 if (!Utility::u2ip(host,l)) 00370 { 00371 SetCloseAndDelete(); 00372 return false; 00373 } 00374 Ipv4Address ad(l, port); 00375 Ipv4Address local; 00376 return Open(ad, local); 00377 #ifdef ENABLE_RESOLVER 00378 } 00379 // resolve using async resolver thread 00380 m_resolver_id = Resolve(host, port); 00381 return true; 00382 #endif 00383 }
void TcpSocket::OnConnectTimeout | ( | ) | [virtual] |
Connect timeout callback.
Reimplemented from Socket.
Definition at line 1724 of file TcpSocket.cpp.
References StreamSocket::GetConnectionRetries(), StreamSocket::GetConnectionRetry(), Socket::Handler(), StreamSocket::IncreaseConnectionRetries(), LOG_LEVEL_FATAL, ISocketHandler::LogError(), Socket::OnConnectFailed(), Socket::OnConnectRetry(), OnSocks4ConnectFailed(), Socket::SetCloseAndDelete(), StreamSocket::SetConnecting(), Socket::SetRetryClientConnect(), and Socket::Socks4().
01725 { 01726 Handler().LogError(this, "connect", -1, "connect timeout", LOG_LEVEL_FATAL); 01727 #ifdef ENABLE_SOCKS4 01728 if (Socks4()) 01729 { 01730 OnSocks4ConnectFailed(); 01731 // retry direct connection 01732 } 01733 else 01734 #endif 01735 if (GetConnectionRetry() == -1 || 01736 (GetConnectionRetry() && GetConnectionRetries() < GetConnectionRetry()) ) 01737 { 01738 IncreaseConnectionRetries(); 01739 // ask socket via OnConnectRetry callback if we should continue trying 01740 if (OnConnectRetry()) 01741 { 01742 SetRetryClientConnect(); 01743 } 01744 else 01745 { 01746 SetCloseAndDelete( true ); 01748 OnConnectFailed(); 01749 // 01750 SetConnecting(false); 01751 } 01752 } 01753 else 01754 { 01755 SetCloseAndDelete(true); 01757 OnConnectFailed(); 01758 // 01759 SetConnecting(false); 01760 } 01761 }
int TcpSocket::Close | ( | ) | [virtual] |
Close file descriptor - internal use only.
Reimplemented from Socket.
Definition at line 1400 of file TcpSocket.cpp.
References Socket::Close(), Errno, StreamSocket::GetShutdown(), Socket::GetSocket(), Socket::Handler(), INVALID_SOCKET, Socket::IsConnected(), Socket::IsSSL(), LOG_LEVEL_ERROR, LOG_LEVEL_WARNING, ISocketHandler::LogError(), Socket::Lost(), m_ssl, Socket::SetNonblocking(), and StrError.
01401 { 01402 if (GetSocket() == INVALID_SOCKET) // this could happen 01403 { 01404 Handler().LogError(this, "Socket::Close", 0, "file descriptor invalid", LOG_LEVEL_WARNING); 01405 return 0; 01406 } 01407 int n; 01408 SetNonblocking(true); 01409 if (!Lost() && IsConnected() && !(GetShutdown() & SHUT_WR)) 01410 { 01411 if (shutdown(GetSocket(), SHUT_WR) == -1) 01412 { 01413 // failed... 01414 Handler().LogError(this, "shutdown", Errno, StrError(Errno), LOG_LEVEL_ERROR); 01415 } 01416 } 01417 // 01418 char tmp[1000]; 01419 if (!Lost() && (n = recv(GetSocket(),tmp,1000,0)) >= 0) 01420 { 01421 if (n) 01422 { 01423 Handler().LogError(this, "read() after shutdown", n, "bytes read", LOG_LEVEL_WARNING); 01424 } 01425 } 01426 #ifdef HAVE_OPENSSL 01427 if (IsSSL() && m_ssl) 01428 SSL_shutdown(m_ssl); 01429 if (m_ssl) 01430 { 01431 SSL_free(m_ssl); 01432 m_ssl = NULL; 01433 } 01434 #endif 01435 return Socket::Close(); 01436 }
void TcpSocket::Send | ( | const std::string & | s, | |
int | f = 0 | |||
) | [virtual] |
Send a string.
s | String to send | |
f | Dummy flags -- not used |
Reimplemented from Socket.
Definition at line 888 of file TcpSocket.cpp.
References SendBuf().
Referenced by HttpPostSocket::DoMultipartPost(), SmtpdSocket::OnAccept(), ResolvSocket::OnConnect(), HttpPostSocket::OnConnect(), HttpDebugSocket::OnData(), HttpDebugSocket::OnDataComplete(), ResolvSocket::OnDetached(), HttpDebugSocket::OnFirst(), HttpDebugSocket::OnHeader(), HttpDebugSocket::OnHeaderComplete(), SmtpdSocket::OnLine(), ResolvSocket::OnLine(), Sendf(), HTTPSocket::SendRequest(), and HTTPSocket::SendResponse().
00889 { 00890 SendBuf(str.c_str(),str.size(),i); 00891 }
void TcpSocket::Sendf | ( | const char * | format, | |
... | ||||
) |
Send string using printf formatting.
Definition at line 1083 of file TcpSocket.cpp.
References Send().
Referenced by HttpDebugSocket::OnFirst().
01084 { 01085 va_list ap; 01086 va_start(ap, format); 01087 char slask[5000]; // vsprintf / vsnprintf temporary 01088 vsnprintf(slask, sizeof(slask), format, ap); 01089 va_end(ap); 01090 Send( slask ); 01091 }
void TcpSocket::SendBuf | ( | const char * | buf, | |
size_t | len, | |||
int | f = 0 | |||
) | [virtual] |
Send buffer of bytes.
buf | Buffer pointer | |
len | Length of data | |
f | Dummy flags -- not used |
Reimplemented from Socket.
Definition at line 894 of file TcpSocket.cpp.
References Buffer(), Socket::CloseAndDelete(), StreamSocket::Connecting(), Socket::GetSocket(), Socket::Handler(), INVALID_SOCKET, Socket::IsConnected(), Socket::IsDisableRead(), ISocketHandler::ISocketHandler_Mod(), Socket::IsSSL(), LOG_LEVEL_INFO, ISocketHandler::LogError(), m_obuf, m_obuf_top, StreamSocket::Ready(), SendFromOutputBuffer(), and TryWrite().
Referenced by HttpPostSocket::DoMultipartPost(), Ajp13Socket::IHttpServer_Respond(), HttpPutSocket::OnConnect(), HttpDebugSocket::OnData(), OnSocks4Connect(), HttpBaseSocket::OnTransferLimit(), Ajp13Socket::OnTransferLimit(), Ajp13Socket::ReceiveBody(), Ajp13Socket::ReceiveCPing(), Send(), and HttpdSocket::Send64().
00895 { 00896 if (!Ready() && !Connecting()) 00897 { 00898 Handler().LogError(this, "SendBuf", -1, "Attempt to write to a non-ready socket" ); // warning 00899 if (GetSocket() == INVALID_SOCKET) 00900 Handler().LogError(this, "SendBuf", 0, " * GetSocket() == INVALID_SOCKET", LOG_LEVEL_INFO); 00901 if (Connecting()) 00902 Handler().LogError(this, "SendBuf", 0, " * Connecting()", LOG_LEVEL_INFO); 00903 if (CloseAndDelete()) 00904 Handler().LogError(this, "SendBuf", 0, " * CloseAndDelete()", LOG_LEVEL_INFO); 00905 return; 00906 } 00907 if (!IsConnected()) 00908 { 00909 Handler().LogError(this, "SendBuf", -1, "Attempt to write to a non-connected socket, will be sent on connect" ); // warning 00910 Buffer(buf, len); 00911 return; 00912 } 00913 if (m_obuf_top) 00914 { 00915 Buffer(buf, len); 00916 return; 00917 } 00918 #ifdef HAVE_OPENSSL 00919 if (IsSSL()) 00920 { 00921 Buffer(buf, len); 00922 SendFromOutputBuffer(); 00923 return; 00924 } 00925 #endif 00926 int n = TryWrite(buf, len); 00927 if (n >= 0 && n < (int)len) 00928 { 00929 Buffer(buf + n, len - n); 00930 } 00931 // if ( data in buffer || !IsConnected ) 00932 // { 00933 // add to buffer 00934 // } 00935 // else 00936 // try_send 00937 // if any data is unsent, buffer it and set m_wfds 00938 00939 // check output buffer set, set/reset m_wfds accordingly 00940 { 00941 bool br = !IsDisableRead(); 00942 if (m_obuf.size()) 00943 Handler().ISocketHandler_Mod(this, br, true); 00944 else 00945 Handler().ISocketHandler_Mod(this, br, false); 00946 } 00947 }
void TcpSocket::OnRawData | ( | const char * | buf, | |
size_t | len | |||
) | [virtual] |
This callback is executed after a successful read from the socket.
buf | Pointer to the data | |
len | Length of the data |
Reimplemented in AjpBaseSocket, and HTTPSocket.
Definition at line 1464 of file TcpSocket.cpp.
Referenced by OnRead().
void TcpSocket::OnWriteComplete | ( | ) | [virtual] |
Called when output buffer has been sent.
Note: Will only be called IF the output buffer has been used. Send's that was successful without needing the output buffer will not generate a call to this method.
Definition at line 672 of file TcpSocket.cpp.
Referenced by SendFromOutputBuffer().
size_t TcpSocket::GetInputLength | ( | ) |
Number of bytes in input buffer.
Definition at line 1469 of file TcpSocket.cpp.
References TcpSocket::CircularBuffer::GetLength(), and ibuf.
Referenced by OnRead(), OnSocks4Read(), and ReadInput().
size_t TcpSocket::ReadInput | ( | char * | buf, | |
size_t | sz | |||
) |
Read from input buffer.
Definition at line 1475 of file TcpSocket.cpp.
References GetInputLength(), ibuf, and TcpSocket::CircularBuffer::Read().
01476 { 01477 size_t sz = max_sz < GetInputLength() ? max_sz : GetInputLength(); 01478 ibuf.Read(buf, sz); 01479 return sz; 01480 }
size_t TcpSocket::GetOutputLength | ( | ) |
Number of bytes in output buffer.
Definition at line 1483 of file TcpSocket.cpp.
References m_output_length.
Referenced by HttpBaseSocket::OnTransferLimit(), Ajp13Socket::OnTransferLimit(), SendFromOutputBuffer(), and SSLNegotiate().
01484 { 01485 return m_output_length; 01486 }
void TcpSocket::OnLine | ( | const std::string & | line | ) | [virtual] |
Callback fires when a socket in line protocol has read one full line.
line | Line read |
Reimplemented from Socket.
Reimplemented in HTTPSocket, ResolvSocket, and SmtpdSocket.
Definition at line 950 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 1489 of file TcpSocket.cpp.
References m_bytes_received.
01490 { 01491 uint64_t z = m_bytes_received; 01492 if (clear) 01493 m_bytes_received = 0; 01494 return z; 01495 }
uint64_t TcpSocket::GetBytesSent | ( | bool | clear = false |
) | [virtual] |
Get counter of number of bytes sent.
Reimplemented from Socket.
Definition at line 1498 of file TcpSocket.cpp.
References m_bytes_sent.
01499 { 01500 uint64_t z = m_bytes_sent; 01501 if (clear) 01502 m_bytes_sent = 0; 01503 return z; 01504 }
void TcpSocket::OnSocks4Connect | ( | ) | [virtual] |
Socks4 specific callback.
Reimplemented from Socket.
Definition at line 969 of file TcpSocket.cpp.
References Socket::GetClientRemoteAddress(), Socket::GetSocks4Userid(), m_socks4_state, and SendBuf().
00970 { 00971 char request[1000]; 00972 memset(request, 0, sizeof(request)); 00973 request[0] = 4; // socks v4 00974 request[1] = 1; // command code: CONNECT 00975 { 00976 std::auto_ptr<SocketAddress> ad = GetClientRemoteAddress(); 00977 if (ad.get()) 00978 { 00979 struct sockaddr *p0 = (struct sockaddr *)*ad; 00980 struct sockaddr_in *p = (struct sockaddr_in *)p0; 00981 if (p -> sin_family == AF_INET) 00982 { 00983 memcpy(request + 2, &p -> sin_port, 2); // nwbo is ok here 00984 memcpy(request + 4, &p -> sin_addr, sizeof(struct in_addr)); 00985 } 00986 else 00987 { 00989 } 00990 } 00991 else 00992 { 00994 } 00995 } 00996 #if defined( _WIN32) && !defined(__CYGWIN__) 00997 strcpy_s(request + 8, sizeof(request) - 8, GetSocks4Userid().c_str()); 00998 #else 00999 strcpy(request + 8, GetSocks4Userid().c_str()); 01000 #endif 01001 size_t length = GetSocks4Userid().size() + 8 + 1; 01002 SendBuf(request, length); 01003 m_socks4_state = 0; 01004 }
void TcpSocket::OnSocks4ConnectFailed | ( | ) | [virtual] |
Socks4 specific callback.
Reimplemented from Socket.
Definition at line 1007 of file TcpSocket.cpp.
References Socket::Handler(), LOG_LEVEL_WARNING, ISocketHandler::LogError(), Socket::OnConnectFailed(), Socket::SetCloseAndDelete(), StreamSocket::SetConnecting(), and Socket::SetRetryClientConnect().
Referenced by OnConnectTimeout(), and OnWrite().
01008 { 01009 Handler().LogError(this,"OnSocks4ConnectFailed",0,"connection to socks4 server failed, trying direct connection",LOG_LEVEL_WARNING); 01010 if (!Handler().Socks4TryDirect()) 01011 { 01012 SetConnecting(false); 01013 SetCloseAndDelete(); 01014 OnConnectFailed(); // just in case 01015 } 01016 else 01017 { 01018 SetRetryClientConnect(); 01019 } 01020 }
bool TcpSocket::OnSocks4Read | ( | ) | [virtual] |
Socks4 specific callback.
Reimplemented from Socket.
Definition at line 1023 of file TcpSocket.cpp.
References GetInputLength(), Socket::Handler(), ibuf, LOG_LEVEL_FATAL, LOG_LEVEL_INFO, ISocketHandler::LogError(), m_socks4_cd, m_socks4_dstip, m_socks4_dstport, m_socks4_state, m_socks4_vn, Socket::OnConnect(), Socket::OnConnectFailed(), TcpSocket::CircularBuffer::Read(), Socket::SetCloseAndDelete(), StreamSocket::SetConnecting(), and Socket::SetSocks4().
Referenced by OnRead().
01024 { 01025 switch (m_socks4_state) 01026 { 01027 case 0: 01028 ibuf.Read(&m_socks4_vn, 1); 01029 m_socks4_state = 1; 01030 break; 01031 case 1: 01032 ibuf.Read(&m_socks4_cd, 1); 01033 m_socks4_state = 2; 01034 break; 01035 case 2: 01036 if (GetInputLength() > 1) 01037 { 01038 ibuf.Read( (char *)&m_socks4_dstport, 2); 01039 m_socks4_state = 3; 01040 } 01041 else 01042 { 01043 return true; 01044 } 01045 break; 01046 case 3: 01047 if (GetInputLength() > 3) 01048 { 01049 ibuf.Read( (char *)&m_socks4_dstip, 4); 01050 SetSocks4(false); 01051 01052 switch (m_socks4_cd) 01053 { 01054 case 90: 01055 OnConnect(); 01056 Handler().LogError(this, "OnSocks4Read", 0, "Connection established", LOG_LEVEL_INFO); 01057 break; 01058 case 91: 01059 case 92: 01060 case 93: 01061 Handler().LogError(this,"OnSocks4Read",m_socks4_cd,"socks4 server reports connect failed",LOG_LEVEL_FATAL); 01062 SetConnecting(false); 01063 SetCloseAndDelete(); 01064 OnConnectFailed(); 01065 break; 01066 default: 01067 Handler().LogError(this,"OnSocks4Read",m_socks4_cd,"socks4 server unrecognized response",LOG_LEVEL_FATAL); 01068 SetCloseAndDelete(); 01069 break; 01070 } 01071 } 01072 else 01073 { 01074 return true; 01075 } 01076 break; 01077 } 01078 return false; 01079 }
Callback executed when resolver thread has finished a resolve request.
Reimplemented from Socket.
Definition at line 387 of file TcpSocket.cpp.
References ISocketHandler::Add(), DEB, Socket::Handler(), LOG_LEVEL_FATAL, ISocketHandler::LogError(), m_resolver_id, Open(), and Socket::SetCloseAndDelete().
Referenced by ResolvSocket::OnLine().
00388 { 00389 DEB( fprintf(stderr, "TcpSocket::OnResolved id %d addr %x port %d\n", id, a, port);) 00390 if (id == m_resolver_id) 00391 { 00392 if (a && port) 00393 { 00394 Ipv4Address ad(a, port); 00395 Ipv4Address local; 00396 if (Open(ad, local)) 00397 { 00398 if (!Handler().Valid(this)) 00399 { 00400 Handler().Add(this); 00401 } 00402 } 00403 } 00404 else 00405 { 00406 Handler().LogError(this, "OnResolved", 0, "Resolver failed", LOG_LEVEL_FATAL); 00407 SetCloseAndDelete(); 00408 } 00409 } 00410 else 00411 { 00412 Handler().LogError(this, "OnResolved", id, "Resolver returned wrong job id", LOG_LEVEL_FATAL); 00413 SetCloseAndDelete(); 00414 } 00415 }
void TcpSocket::OnSSLConnect | ( | ) | [virtual] |
Callback for 'New' ssl support - replaces SSLSocket.
Internal use.
Reimplemented from Socket.
Definition at line 1095 of file TcpSocket.cpp.
References DEB, Socket::GetSocket(), InitSSLClient(), m_sbio, m_ssl, m_ssl_ctx, Socket::SetCloseAndDelete(), Socket::SetNonblocking(), Socket::SetSSLNegotiate(), and SSLNegotiate().
01096 { 01097 SetNonblocking(true); 01098 { 01099 if (m_ssl_ctx) 01100 { 01101 DEB( fprintf(stderr, "SSL Context already initialized - closing socket\n");) 01102 SetCloseAndDelete(true); 01103 return; 01104 } 01105 InitSSLClient(); 01106 } 01107 if (m_ssl_ctx) 01108 { 01109 /* Connect the SSL socket */ 01110 m_ssl = SSL_new(m_ssl_ctx); 01111 if (!m_ssl) 01112 { 01113 DEB( fprintf(stderr, " m_ssl is NULL\n");) 01114 SetCloseAndDelete(true); 01115 return; 01116 } 01117 m_sbio = BIO_new_socket((int)GetSocket(), BIO_NOCLOSE); 01118 if (!m_sbio) 01119 { 01120 DEB( fprintf(stderr, " m_sbio is NULL\n");) 01121 SetCloseAndDelete(true); 01122 return; 01123 } 01124 SSL_set_bio(m_ssl, m_sbio, m_sbio); 01125 if (!SSLNegotiate()) 01126 { 01127 SetSSLNegotiate(); 01128 } 01129 } 01130 else 01131 { 01132 SetCloseAndDelete(); 01133 } 01134 }
void TcpSocket::OnSSLAccept | ( | ) | [virtual] |
Callback for 'New' ssl support - replaces SSLSocket.
Internal use.
Reimplemented from Socket.
Definition at line 1137 of file TcpSocket.cpp.
References DEB, Socket::GetSocket(), InitSSLServer(), m_sbio, m_ssl, m_ssl_ctx, Socket::SetCloseAndDelete(), Socket::SetNonblocking(), Socket::SetSSLNegotiate(), and Socket::SetSSLServer().
01138 { 01139 SetNonblocking(true); 01140 { 01141 if (m_ssl_ctx) 01142 { 01143 DEB( fprintf(stderr, "SSL Context already initialized - closing socket\n");) 01144 SetCloseAndDelete(true); 01145 return; 01146 } 01147 InitSSLServer(); 01148 SetSSLServer(); 01149 } 01150 if (m_ssl_ctx) 01151 { 01152 m_ssl = SSL_new(m_ssl_ctx); 01153 if (!m_ssl) 01154 { 01155 DEB( fprintf(stderr, " m_ssl is NULL\n");) 01156 SetCloseAndDelete(true); 01157 return; 01158 } 01159 m_sbio = BIO_new_socket((int)GetSocket(), BIO_NOCLOSE); 01160 if (!m_sbio) 01161 { 01162 DEB( fprintf(stderr, " m_sbio is NULL\n");) 01163 SetCloseAndDelete(true); 01164 return; 01165 } 01166 SSL_set_bio(m_ssl, m_sbio, m_sbio); 01167 // if (!SSLNegotiate()) 01168 { 01169 SetSSLNegotiate(); 01170 } 01171 } 01172 }
void TcpSocket::InitSSLClient | ( | ) | [virtual] |
This method must be implemented to initialize the ssl context for an outgoing connection.
Definition at line 1266 of file TcpSocket.cpp.
References InitializeContext().
Referenced by OnSSLConnect().
01267 { 01268 InitializeContext("", SSLv23_method()); 01269 }
void TcpSocket::InitSSLServer | ( | ) | [virtual] |
This method must be implemented to initialize the ssl context for an incoming connection.
Definition at line 1272 of file TcpSocket.cpp.
References Socket::Handler(), LOG_LEVEL_FATAL, ISocketHandler::LogError(), and Socket::SetCloseAndDelete().
Referenced by OnSSLAccept().
01273 { 01274 Handler().LogError(this, "InitSSLServer", 0, "You MUST implement your own InitSSLServer method", LOG_LEVEL_FATAL); 01275 SetCloseAndDelete(); 01276 }
void TcpSocket::SetReconnect | ( | bool | x = true |
) |
Flag that says a broken connection will try to reconnect.
Definition at line 1457 of file TcpSocket.cpp.
References m_b_reconnect.
01458 { 01459 m_b_reconnect = x; 01460 }
bool TcpSocket::Reconnect | ( | ) |
Check reconnect on lost connection flag status.
Definition at line 1508 of file TcpSocket.cpp.
References m_b_reconnect.
Referenced by Open().
01509 { 01510 return m_b_reconnect; 01511 }
void TcpSocket::SetIsReconnect | ( | bool | x = true |
) |
Flag to determine if a reconnect is in progress.
Definition at line 1514 of file TcpSocket.cpp.
References m_b_is_reconnect.
01515 { 01516 m_b_is_reconnect = x; 01517 }
bool TcpSocket::IsReconnect | ( | ) |
Socket is reconnecting.
Definition at line 1520 of file TcpSocket.cpp.
References m_b_is_reconnect.
Referenced by SSLNegotiate().
01521 { 01522 return m_b_is_reconnect; 01523 }
void TcpSocket::DisableInputBuffer | ( | bool | x = true |
) |
Use this if you only use OnRawData to process received data.
Definition at line 1535 of file TcpSocket.cpp.
References m_b_input_buffer_disabled.
Referenced by HTTPSocket::HTTPSocket(), and SetLineProtocol().
01536 { 01537 m_b_input_buffer_disabled = x; 01538 }
void TcpSocket::OnOptions | ( | int | family, | |
int | type, | |||
int | protocol, | |||
SOCKET | s | |||
) | [virtual] |
Called when a client socket is created, to set socket options.
family | AF_INET, AF_INET6, etc | |
type | SOCK_STREAM, SOCK_DGRAM, etc | |
protocol | Protocol number (tcp, udp, sctp, etc) | |
s | Socket file descriptor |
Implements Socket.
Definition at line 1541 of file TcpSocket.cpp.
References DEB, Socket::SetSoKeepalive(), and Socket::SetSoReuseaddr().
01542 { 01543 DEB( fprintf(stderr, "Socket::OnOptions()\n");) 01544 #ifdef SO_NOSIGPIPE 01545 SetSoNosigpipe(true); 01546 #endif 01547 SetSoReuseaddr(true); 01548 SetSoKeepalive(true); 01549 }
void TcpSocket::SetLineProtocol | ( | bool | x = true |
) | [virtual] |
Called after OnRead if socket is in line protocol mode.
Reimplemented from StreamSocket.
Definition at line 1552 of file TcpSocket.cpp.
References DisableInputBuffer(), and StreamSocket::SetLineProtocol().
Referenced by HTTPSocket::HTTPSocket(), HTTPSocket::OnLine(), HTTPSocket::OnRawData(), HTTPSocket::Reset(), ResolvSocket::ResolvSocket(), and SmtpdSocket::SmtpdSocket().
01553 { 01554 StreamSocket::SetLineProtocol(x); 01555 DisableInputBuffer(x); 01556 }
const std::string TcpSocket::GetLine | ( | ) | const |
Get the unfinished line when using SetLineProtocol = true.
The finished line will always be reported with a call to OnLine.
Definition at line 1559 of file TcpSocket.cpp.
References m_line, and m_line_ptr.
01560 { 01561 if (!m_line_ptr) 01562 return ""; 01563 return std::string(&m_line[0], m_line_ptr); 01564 }
bool TcpSocket::SetTcpNodelay | ( | bool | x = true |
) |
Definition at line 1567 of file TcpSocket.cpp.
References Errno, Socket::GetSocket(), Socket::Handler(), LOG_LEVEL_FATAL, LOG_LEVEL_INFO, ISocketHandler::LogError(), and StrError.
01568 { 01569 #ifdef TCP_NODELAY 01570 int optval = x ? 1 : 0; 01571 if (setsockopt(GetSocket(), IPPROTO_TCP, TCP_NODELAY, (char *)&optval, sizeof(optval)) == -1) 01572 { 01573 Handler().LogError(this, "setsockopt(IPPROTO_TCP, TCP_NODELAY)", Errno, StrError(Errno), LOG_LEVEL_FATAL); 01574 return false; 01575 } 01576 return true; 01577 #else 01578 Handler().LogError(this, "socket option not available", 0, "TCP_NODELAY", LOG_LEVEL_INFO); 01579 return false; 01580 #endif 01581 }
int TcpSocket::Protocol | ( | ) | [virtual] |
Returns IPPROTO_TCP or IPPROTO_SCTP.
Implements StreamSocket.
Definition at line 1800 of file TcpSocket.cpp.
void TcpSocket::SetTransferLimit | ( | size_t | sz | ) |
Trigger limit for callback OnTransferLimit.
Definition at line 1806 of file TcpSocket.cpp.
References m_transfer_limit.
Referenced by HttpBaseSocket::OnTransferLimit(), and Ajp13Socket::OnTransferLimit().
01807 { 01808 m_transfer_limit = sz; 01809 }
void TcpSocket::OnTransferLimit | ( | ) | [virtual] |
This callback fires when the output buffer drops below the value set by SetTransferLimit.
Default: 0 (disabled).
Reimplemented in Ajp13Socket, and HttpBaseSocket.
Definition at line 1812 of file TcpSocket.cpp.
Referenced by SendFromOutputBuffer().
void TcpSocket::OnRead | ( | ) | [protected, virtual] |
Called when there is something to be read from the file descriptor.
Reimplemented from Socket.
Definition at line 446 of file TcpSocket.cpp.
References DEB, Errno, Socket::GetSocket(), Socket::GetTrafficMonitor(), Socket::Handler(), ibuf, Socket::IsSSL(), LOG_LEVEL_ERROR, LOG_LEVEL_FATAL, LOG_LEVEL_WARNING, ISocketHandler::LogError(), m_b_input_buffer_disabled, m_buf, m_bytes_received, m_ssl, Socket::OnDisconnect(), StreamSocket::Ready(), Socket::SetCloseAndDelete(), StreamSocket::SetFlushBeforeClose(), Socket::SetLost(), StreamSocket::SetShutdown(), StrError, TCP_BUFSIZE_READ, TCP_DISCONNECT_ERROR, TCP_DISCONNECT_SSL, and TcpSocket::CircularBuffer::Write().
Referenced by HTTPSocket::OnRawData().
00447 { 00448 int n = 0; 00449 #ifdef SOCKETS_DYNAMIC_TEMP 00450 char *buf = m_buf; 00451 #else 00452 char buf[TCP_BUFSIZE_READ]; 00453 #endif 00454 #ifdef HAVE_OPENSSL 00455 if (IsSSL()) 00456 { 00457 if (!Ready()) 00458 return; 00459 n = SSL_read(m_ssl, buf, TCP_BUFSIZE_READ); 00460 if (n == -1) 00461 { 00462 n = SSL_get_error(m_ssl, n); 00463 switch (n) 00464 { 00465 case SSL_ERROR_NONE: 00466 case SSL_ERROR_WANT_READ: 00467 case SSL_ERROR_WANT_WRITE: 00468 break; 00469 case SSL_ERROR_ZERO_RETURN: 00470 DEB( fprintf(stderr, "SSL_read() returns zero - closing socket\n");) 00471 OnDisconnect(); 00472 OnDisconnect(TCP_DISCONNECT_SSL|TCP_DISCONNECT_ERROR, n); 00473 SetCloseAndDelete(true); 00474 SetFlushBeforeClose(false); 00475 SetLost(); 00476 break; 00477 default: 00478 DEB( fprintf(stderr, "SSL read problem, errcode = %d\n",n);) 00479 OnDisconnect(); 00480 OnDisconnect(TCP_DISCONNECT_SSL|TCP_DISCONNECT_ERROR, n); 00481 SetCloseAndDelete(true); 00482 SetFlushBeforeClose(false); 00483 SetLost(); 00484 } 00485 return; 00486 } 00487 else 00488 if (!n) 00489 { 00490 DEB( n = SSL_get_error(m_ssl, n); 00491 fprintf(stderr, "SSL_read returns 0, SSL_get_error: %d\n", n); 00492 if (n == SSL_ERROR_SYSCALL) 00493 { 00494 fprintf(stderr, "ERR_get_error() returns %ld\n", ERR_get_error()); 00495 perror("errno: SSL_read"); 00496 }) 00497 OnDisconnect(); 00498 OnDisconnect(TCP_DISCONNECT_SSL, 0); 00499 SetCloseAndDelete(true); 00500 SetFlushBeforeClose(false); 00501 SetLost(); 00502 SetShutdown(SHUT_WR); 00503 return; 00504 } 00505 else 00506 if (n > 0 && n <= TCP_BUFSIZE_READ) 00507 { 00508 m_bytes_received += n; 00509 if (GetTrafficMonitor()) 00510 { 00511 GetTrafficMonitor() -> fwrite(buf, 1, n); 00512 } 00513 if (!m_b_input_buffer_disabled && !ibuf.Write(buf,n)) 00514 { 00515 Handler().LogError(this, "OnRead(ssl)", 0, "ibuf overflow", LOG_LEVEL_WARNING); 00516 } 00517 } 00518 else 00519 { 00520 Handler().LogError(this, "OnRead(ssl)", n, "abnormal value from SSL_read", LOG_LEVEL_ERROR); 00521 } 00522 } 00523 else 00524 #endif // HAVE_OPENSSL 00525 { 00526 n = recv(GetSocket(), buf, TCP_BUFSIZE_READ, MSG_NOSIGNAL); 00527 if (n == -1) 00528 { 00529 Handler().LogError(this, "read", Errno, StrError(Errno), LOG_LEVEL_FATAL); 00530 OnDisconnect(); 00531 OnDisconnect(TCP_DISCONNECT_ERROR, Errno); 00532 SetCloseAndDelete(true); 00533 SetFlushBeforeClose(false); 00534 SetLost(); 00535 return; 00536 } 00537 else 00538 if (!n) 00539 { 00540 OnDisconnect(); 00541 OnDisconnect(0, 0); 00542 SetCloseAndDelete(true); 00543 SetFlushBeforeClose(false); 00544 SetLost(); 00545 SetShutdown(SHUT_WR); 00546 return; 00547 } 00548 else 00549 if (n > 0 && n <= TCP_BUFSIZE_READ) 00550 { 00551 m_bytes_received += n; 00552 if (GetTrafficMonitor()) 00553 { 00554 GetTrafficMonitor() -> fwrite(buf, 1, n); 00555 } 00556 if (!m_b_input_buffer_disabled && !ibuf.Write(buf,n)) 00557 { 00558 Handler().LogError(this, "OnRead", 0, "ibuf overflow", LOG_LEVEL_WARNING); 00559 } 00560 } 00561 else 00562 { 00563 Handler().LogError(this, "OnRead", n, "abnormal value from recv", LOG_LEVEL_ERROR); 00564 } 00565 } 00566 // 00567 OnRead( buf, n ); 00568 }
void TcpSocket::OnRead | ( | char * | buf, | |
size_t | n | |||
) | [protected] |
Definition at line 571 of file TcpSocket.cpp.
References Socket::CloseAndDelete(), GetInputLength(), Socket::Handler(), StreamSocket::LineProtocol(), LOG_LEVEL_FATAL, ISocketHandler::LogError(), m_b_input_buffer_disabled, m_c, m_line, m_line_ptr, m_skip_c, OnLine(), OnRawData(), OnSocks4Read(), Socket::SetCloseAndDelete(), Socket::Socks4(), and TCP_BUFSIZE_READ.
00572 { 00573 // unbuffered 00574 if (n > 0 && n <= TCP_BUFSIZE_READ) 00575 { 00576 if (LineProtocol()) 00577 { 00578 buf[n] = 0; 00579 size_t i = 0; 00580 if (m_skip_c && (buf[i] == 13 || buf[i] == 10) && buf[i] != m_c) 00581 { 00582 m_skip_c = false; 00583 i++; 00584 } 00585 size_t x = i; 00586 for (; i < n && LineProtocol(); i++) 00587 { 00588 while ((buf[i] == 13 || buf[i] == 10) && LineProtocol()) 00589 { 00590 char c = buf[i]; 00591 buf[i] = 0; 00592 if (buf[x]) 00593 { 00594 size_t sz = strlen(&buf[x]); 00595 if (m_line_ptr + sz < Handler().MaxTcpLineSize()) 00596 { 00597 memcpy(&m_line[m_line_ptr], &buf[x], sz); 00598 m_line_ptr += sz; 00599 } 00600 else 00601 { 00602 Handler().LogError(this, "TcpSocket::OnRead", (int)(m_line_ptr + sz), "maximum tcp_line_size exceeded, connection closed", LOG_LEVEL_FATAL); 00603 SetCloseAndDelete(); 00604 } 00605 } 00606 if (m_line_ptr > 0) 00607 OnLine( std::string(&m_line[0], m_line_ptr) ); 00608 else 00609 OnLine( "" ); 00610 i++; 00611 m_skip_c = true; 00612 m_c = c; 00613 if (i < n && (buf[i] == 13 || buf[i] == 10) && buf[i] != c) 00614 { 00615 m_skip_c = false; 00616 i++; 00617 } 00618 x = i; 00619 m_line_ptr = 0; 00620 } 00621 if (!LineProtocol()) 00622 { 00623 break; 00624 } 00625 } 00626 if (!LineProtocol()) 00627 { 00628 if (i < n) 00629 { 00630 OnRawData(buf + i, n - i); 00631 } 00632 } 00633 else 00634 if (buf[x]) 00635 { 00636 size_t sz = strlen(&buf[x]); 00637 if (m_line_ptr + sz < Handler().MaxTcpLineSize()) 00638 { 00639 memcpy(&m_line[m_line_ptr], &buf[x], sz); 00640 m_line_ptr += sz; 00641 } 00642 else 00643 { 00644 Handler().LogError(this, "TcpSocket::OnRead", (int)(m_line_ptr + sz), "maximum tcp_line_size exceeded, connection closed", LOG_LEVEL_FATAL); 00645 SetCloseAndDelete(); 00646 } 00647 } 00648 } 00649 else 00650 { 00651 OnRawData(buf, n); 00652 } 00653 } 00654 if (m_b_input_buffer_disabled) 00655 { 00656 return; 00657 } 00658 // further processing: socks4 00659 #ifdef ENABLE_SOCKS4 00660 if (Socks4()) 00661 { 00662 bool need_more = false; 00663 while (GetInputLength() && !need_more && !CloseAndDelete()) 00664 { 00665 need_more = OnSocks4Read(); 00666 } 00667 } 00668 #endif 00669 }
void TcpSocket::OnWrite | ( | ) | [protected, virtual] |
Called when there is room for another write on the file descriptor.
Reimplemented from Socket.
Definition at line 677 of file TcpSocket.cpp.
References StreamSocket::Connecting(), StreamSocket::GetConnectionRetries(), StreamSocket::GetConnectionRetry(), Socket::Handler(), Socket::IsDisableRead(), ISocketHandler::ISocketHandler_Mod(), LOG_LEVEL_FATAL, ISocketHandler::LogError(), Socket::OnConnectFailed(), OnSocks4ConnectFailed(), SendFromOutputBuffer(), Socket::SetCallOnConnect(), Socket::SetCloseAndDelete(), StreamSocket::SetConnecting(), Socket::Socks4(), Socket::SoError(), and StrError.
Referenced by SSLNegotiate().
00678 { 00679 if (Connecting()) 00680 { 00681 int err = SoError(); 00682 00683 // don't reset connecting flag on error here, we want the OnConnectFailed timeout later on 00684 if (!err) // ok 00685 { 00686 Handler().ISocketHandler_Mod(this, !IsDisableRead(), false); 00687 SetConnecting(false); 00688 SetCallOnConnect(); 00689 return; 00690 } 00691 Handler().LogError(this, "tcp: connect failed", err, StrError(err), LOG_LEVEL_FATAL); 00692 Handler().ISocketHandler_Mod(this, false, false); // no more monitoring because connection failed 00693 00694 // failed 00695 #ifdef ENABLE_SOCKS4 00696 if (Socks4()) 00697 { 00698 // %! leave 'Connecting' flag set? 00699 OnSocks4ConnectFailed(); 00700 return; 00701 } 00702 #endif 00703 if (GetConnectionRetry() == -1 || 00704 (GetConnectionRetry() && GetConnectionRetries() < GetConnectionRetry()) ) 00705 { 00706 // even though the connection failed at once, only retry after 00707 // the connection timeout. 00708 // should we even try to connect again, when CheckConnect returns 00709 // false it's because of a connection error - not a timeout... 00710 return; 00711 } 00712 SetConnecting(false); 00713 SetCloseAndDelete( true ); 00715 OnConnectFailed(); 00716 return; 00717 } 00718 00719 SendFromOutputBuffer(); 00720 }
void TcpSocket::InitializeContext | ( | const std::string & | context, | |
const SSL_METHOD * | meth_in = NULL | |||
) | [protected] |
SSL; Initialize ssl context for a client socket.
meth_in | SSL method |
Definition at line 1279 of file TcpSocket.cpp.
References m_client_contexts, and m_ssl_ctx.
Referenced by InitializeContext(), and InitSSLClient().
01280 { 01281 static Mutex mutex; 01282 Lock lock(mutex); 01283 /* Create our context*/ 01284 if (m_client_contexts.find(context) == m_client_contexts.end()) 01285 { 01286 const SSL_METHOD *meth = meth_in ? meth_in : SSLv3_method(); 01287 m_ssl_ctx = m_client_contexts[context] = SSL_CTX_new(const_cast<SSL_METHOD *>(meth)); 01288 SSL_CTX_set_mode(m_ssl_ctx, SSL_MODE_AUTO_RETRY|SSL_MODE_ENABLE_PARTIAL_WRITE); 01289 } 01290 else 01291 { 01292 m_ssl_ctx = m_client_contexts[context]; 01293 } 01294 }
void TcpSocket::InitializeContext | ( | const std::string & | context, | |
const std::string & | keyfile, | |||
const std::string & | password, | |||
const SSL_METHOD * | meth_in = NULL | |||
) | [protected] |
SSL; Initialize ssl context for a server socket.
keyfile | Combined private key/certificate file | |
password | Password for private key | |
meth_in | SSL method |
Definition at line 1297 of file TcpSocket.cpp.
References InitializeContext().
01298 { 01299 InitializeContext(context, keyfile, keyfile, password, meth_in); 01300 /* 01301 Lock lock(m_server_ssl_mutex); 01302 // Create our context 01303 if (m_server_contexts.find(context) == m_server_contexts.end()) 01304 { 01305 const SSL_METHOD *meth = meth_in ? meth_in : SSLv3_method(); 01306 m_ssl_ctx = m_server_contexts[context] = SSL_CTX_new(const_cast<SSL_METHOD *>(meth)); 01307 SSL_CTX_set_mode(m_ssl_ctx, SSL_MODE_AUTO_RETRY|SSL_MODE_ENABLE_PARTIAL_WRITE); 01308 // session id 01309 if (context.size()) 01310 SSL_CTX_set_session_id_context(m_ssl_ctx, (const unsigned char *)context.c_str(), (unsigned int)context.size()); 01311 else 01312 SSL_CTX_set_session_id_context(m_ssl_ctx, (const unsigned char *)"--empty--", 9); 01313 } 01314 else 01315 { 01316 m_ssl_ctx = m_server_contexts[context]; 01317 } 01318 01319 // Load our keys and certificates 01320 if (!(SSL_CTX_use_certificate_file(m_ssl_ctx, keyfile.c_str(), SSL_FILETYPE_PEM))) 01321 { 01322 Handler().LogError(this, "TcpSocket InitializeContext", 0, "Couldn't read certificate file " + keyfile, LOG_LEVEL_FATAL); 01323 } 01324 01325 m_password = password; 01326 SSL_CTX_set_default_passwd_cb(m_ssl_ctx, SSL_password_cb); 01327 SSL_CTX_set_default_passwd_cb_userdata(m_ssl_ctx, this); 01328 if (!(SSL_CTX_use_PrivateKey_file(m_ssl_ctx, keyfile.c_str(), SSL_FILETYPE_PEM))) 01329 { 01330 Handler().LogError(this, "TcpSocket InitializeContext", 0, "Couldn't read private key file " + keyfile, LOG_LEVEL_FATAL); 01331 } 01332 */ 01333 }
void TcpSocket::InitializeContext | ( | const std::string & | context, | |
const std::string & | certfile, | |||
const std::string & | keyfile, | |||
const std::string & | password, | |||
const SSL_METHOD * | meth_in = NULL | |||
) | [protected] |
SSL; Initialize ssl context for a server socket.
certfile | Separate certificate file | |
keyfile | Combined private key/certificate file | |
password | Password for private key | |
meth_in | SSL method |
Definition at line 1336 of file TcpSocket.cpp.
References Socket::Handler(), LOG_LEVEL_FATAL, ISocketHandler::LogError(), m_password, m_server_contexts, m_server_ssl_mutex, m_ssl_ctx, and SSL_password_cb().
01337 { 01338 Lock lock(m_server_ssl_mutex); 01339 /* Create our context*/ 01340 if (m_server_contexts.find(context) == m_server_contexts.end()) 01341 { 01342 const SSL_METHOD *meth = meth_in ? meth_in : SSLv3_method(); 01343 m_ssl_ctx = m_server_contexts[context] = SSL_CTX_new(const_cast<SSL_METHOD *>(meth)); 01344 SSL_CTX_set_mode(m_ssl_ctx, SSL_MODE_AUTO_RETRY|SSL_MODE_ENABLE_PARTIAL_WRITE); 01345 // session id 01346 if (context.size()) 01347 SSL_CTX_set_session_id_context(m_ssl_ctx, (const unsigned char *)context.c_str(), (unsigned int)context.size()); 01348 else 01349 SSL_CTX_set_session_id_context(m_ssl_ctx, (const unsigned char *)"--empty--", 9); 01350 } 01351 else 01352 { 01353 m_ssl_ctx = m_server_contexts[context]; 01354 } 01355 01356 /* Load our keys and certificates*/ 01357 if (!(SSL_CTX_use_certificate_file(m_ssl_ctx, certfile.c_str(), SSL_FILETYPE_PEM))) 01358 { 01359 Handler().LogError(this, "TcpSocket InitializeContext", 0, "Couldn't read certificate file " + keyfile, LOG_LEVEL_FATAL); 01360 } 01361 01362 m_password = password; 01363 SSL_CTX_set_default_passwd_cb(m_ssl_ctx, SSL_password_cb); 01364 SSL_CTX_set_default_passwd_cb_userdata(m_ssl_ctx, this); 01365 if (!(SSL_CTX_use_PrivateKey_file(m_ssl_ctx, keyfile.c_str(), SSL_FILETYPE_PEM))) 01366 { 01367 Handler().LogError(this, "TcpSocket InitializeContext", 0, "Couldn't read private key file " + keyfile, LOG_LEVEL_FATAL); 01368 } 01369 }
void TcpSocket::UseCertificateChainFile | ( | const std::string & | filename | ) | [protected] |
SSL; load certificate chain from file.
Definition at line 1372 of file TcpSocket.cpp.
References Socket::Handler(), LOG_LEVEL_ERROR, ISocketHandler::LogError(), and m_ssl_ctx.
01373 { 01374 if (!(SSL_CTX_use_certificate_chain_file(m_ssl_ctx, filename.c_str()))) 01375 { 01376 Handler().LogError(this, "TcpSocket UseCertificateChainFile", 0, "Couldn't read certificate file " + filename, LOG_LEVEL_ERROR); 01377 } 01378 }
int TcpSocket::SSL_password_cb | ( | char * | buf, | |
int | num, | |||
int | rwflag, | |||
void * | userdata | |||
) | [static, protected] |
SSL; Password callback method.
Definition at line 1381 of file TcpSocket.cpp.
References GetPassword().
Referenced by InitializeContext().
01382 { 01383 Socket *p0 = static_cast<Socket *>(userdata); 01384 TcpSocket *p = dynamic_cast<TcpSocket *>(p0); 01385 std::string pw = p ? p -> GetPassword() : ""; 01386 if ( (size_t)num < pw.size() + 1) 01387 { 01388 return 0; 01389 } 01390 #if defined( _WIN32) && !defined(__CYGWIN__) 01391 strcpy_s(buf, num, pw.c_str()); 01392 #else 01393 strcpy(buf,pw.c_str()); 01394 #endif 01395 return (int)pw.size(); 01396 }
SSL_CTX * TcpSocket::GetSslContext | ( | ) | [protected, virtual] |
SSL; Get pointer to ssl context structure.
Reimplemented from Socket.
Definition at line 1440 of file TcpSocket.cpp.
References Socket::Handler(), LOG_LEVEL_WARNING, ISocketHandler::LogError(), and m_ssl_ctx.
01441 { 01442 if (!m_ssl_ctx) 01443 Handler().LogError(this, "GetSslContext", 0, "SSL Context is NULL; check InitSSLServer/InitSSLClient", LOG_LEVEL_WARNING); 01444 return m_ssl_ctx; 01445 }
SSL * TcpSocket::GetSsl | ( | ) | [protected, virtual] |
SSL; Get pointer to ssl structure.
Reimplemented from Socket.
Definition at line 1447 of file TcpSocket.cpp.
References Socket::Handler(), LOG_LEVEL_WARNING, ISocketHandler::LogError(), and m_ssl.
01448 { 01449 if (!m_ssl) 01450 Handler().LogError(this, "GetSsl", 0, "SSL is NULL; check InitSSLServer/InitSSLClient", LOG_LEVEL_WARNING); 01451 return m_ssl; 01452 }
bool TcpSocket::SSLNegotiate | ( | ) | [protected, virtual] |
ssl; still negotiating connection.
Reimplemented from Socket.
Definition at line 1175 of file TcpSocket.cpp.
References DEB, GetOutputLength(), Socket::Handler(), IsReconnect(), Socket::IsSSLServer(), LOG_LEVEL_INFO, ISocketHandler::LogError(), m_ssl, Socket::OnAccept(), Socket::OnConnect(), Socket::OnReconnect(), Socket::OnSSLAcceptFailed(), Socket::OnSSLConnectFailed(), OnWrite(), Socket::SetCloseAndDelete(), Socket::SetConnected(), and Socket::SetSSLNegotiate().
Referenced by OnSSLConnect().
01176 { 01177 if (!IsSSLServer()) // client 01178 { 01179 int r = SSL_connect(m_ssl); 01180 if (r > 0) 01181 { 01182 SetSSLNegotiate(false); 01184 // CheckCertificateChain( "");//ServerHOST); 01185 SetConnected(); 01186 if (GetOutputLength()) 01187 { 01188 OnWrite(); 01189 } 01190 #ifdef ENABLE_RECONNECT 01191 if (IsReconnect()) 01192 { 01193 OnReconnect(); 01194 } 01195 else 01196 #endif 01197 { 01198 OnConnect(); 01199 } 01200 Handler().LogError(this, "SSLNegotiate/SSL_connect", 0, "Connection established", LOG_LEVEL_INFO); 01201 return true; 01202 } 01203 else 01204 if (!r) 01205 { 01206 Handler().LogError(this, "SSLNegotiate/SSL_connect", 0, "Connection failed", LOG_LEVEL_INFO); 01207 SetSSLNegotiate(false); 01208 SetCloseAndDelete(); 01209 OnSSLConnectFailed(); 01210 } 01211 else 01212 { 01213 r = SSL_get_error(m_ssl, r); 01214 if (r != SSL_ERROR_WANT_READ && r != SSL_ERROR_WANT_WRITE) 01215 { 01216 Handler().LogError(this, "SSLNegotiate/SSL_connect", -1, "Connection failed", LOG_LEVEL_INFO); 01217 DEB( fprintf(stderr, "SSL_connect() failed - closing socket, return code: %d\n",r);) 01218 SetSSLNegotiate(false); 01219 SetCloseAndDelete(true); 01220 OnSSLConnectFailed(); 01221 } 01222 } 01223 } 01224 else // server 01225 { 01226 int r = SSL_accept(m_ssl); 01227 if (r > 0) 01228 { 01229 SetSSLNegotiate(false); 01231 // CheckCertificateChain( "");//ClientHOST); 01232 SetConnected(); 01233 if (GetOutputLength()) 01234 { 01235 OnWrite(); 01236 } 01237 OnAccept(); 01238 Handler().LogError(this, "SSLNegotiate/SSL_accept", 0, "Connection established", LOG_LEVEL_INFO); 01239 return true; 01240 } 01241 else 01242 if (!r) 01243 { 01244 Handler().LogError(this, "SSLNegotiate/SSL_accept", 0, "Connection failed", LOG_LEVEL_INFO); 01245 SetSSLNegotiate(false); 01246 SetCloseAndDelete(); 01247 OnSSLAcceptFailed(); 01248 } 01249 else 01250 { 01251 r = SSL_get_error(m_ssl, r); 01252 if (r != SSL_ERROR_WANT_READ && r != SSL_ERROR_WANT_WRITE) 01253 { 01254 Handler().LogError(this, "SSLNegotiate/SSL_accept", -1, "Connection failed", LOG_LEVEL_INFO); 01255 DEB( fprintf(stderr, "SSL_accept() failed - closing socket, return code: %d\n",r);) 01256 SetSSLNegotiate(false); 01257 SetCloseAndDelete(true); 01258 OnSSLAcceptFailed(); 01259 } 01260 } 01261 } 01262 return false; 01263 }
const std::string & TcpSocket::GetPassword | ( | ) | [protected] |
SSL; Get ssl password.
Definition at line 1528 of file TcpSocket.cpp.
References m_password.
Referenced by SSL_password_cb().
01529 { 01530 return m_password; 01531 }
void TcpSocket::SendFromOutputBuffer | ( | ) | [private] |
Definition at line 723 of file TcpSocket.cpp.
References GetOutputLength(), Socket::Handler(), Socket::IsDisableRead(), ISocketHandler::ISocketHandler_Mod(), LOG_LEVEL_ERROR, ISocketHandler::LogError(), m_obuf, m_obuf_top, m_output_length, m_transfer_limit, OnTransferLimit(), OnWriteComplete(), and TryWrite().
Referenced by OnWrite(), and SendBuf().
00724 { 00725 // try send next block in buffer 00726 // if full block is sent, repeat 00727 // if all blocks are sent, reset m_wfds 00728 00729 bool repeat = false; 00730 size_t sz = m_transfer_limit ? GetOutputLength() : 0; 00731 do 00732 { 00733 if (m_obuf.empty()) 00734 { 00735 Handler().LogError(this, "OnWrite", (int)m_output_length, "Empty output buffer in OnWrite", LOG_LEVEL_ERROR); 00736 break; 00737 } 00738 output_l::iterator it = m_obuf.begin(); 00739 OUTPUT *p = *it; 00740 repeat = false; 00741 int n = TryWrite(p -> Buf(), p -> Len()); 00742 if (n > 0) 00743 { 00744 size_t left = p -> Remove(n); 00745 m_output_length -= n; 00746 if (!left) 00747 { 00748 delete p; 00749 m_obuf.erase(it); 00750 if (!m_obuf.size()) 00751 { 00752 m_obuf_top = NULL; 00753 OnWriteComplete(); 00754 } 00755 else 00756 { 00757 repeat = true; 00758 } 00759 } 00760 } 00761 } while (repeat); 00762 00763 if (m_transfer_limit && sz > m_transfer_limit && GetOutputLength() < m_transfer_limit) 00764 { 00765 OnTransferLimit(); 00766 } 00767 00768 // check output buffer set, set/reset m_wfds accordingly 00769 { 00770 bool br = !IsDisableRead(); 00771 if (m_obuf.size()) 00772 Handler().ISocketHandler_Mod(this, br, true); 00773 else 00774 Handler().ISocketHandler_Mod(this, br, false); 00775 } 00776 }
int TcpSocket::TryWrite | ( | const char * | buf, | |
size_t | len | |||
) | [private] |
the actual send()
Definition at line 779 of file TcpSocket.cpp.
References Errno, Socket::GetSocket(), Socket::GetTrafficMonitor(), Socket::Handler(), Socket::IsSSL(), LOG_LEVEL_FATAL, ISocketHandler::LogError(), m_bytes_sent, m_repeat_length, m_ssl, Socket::OnDisconnect(), Socket::SetCloseAndDelete(), StreamSocket::SetFlushBeforeClose(), Socket::SetLost(), StrError, TCP_DISCONNECT_ERROR, TCP_DISCONNECT_SSL, and TCP_DISCONNECT_WRITE.
Referenced by SendBuf(), and SendFromOutputBuffer().
00780 { 00781 int n = 0; 00782 #ifdef HAVE_OPENSSL 00783 if (IsSSL()) 00784 { 00785 n = SSL_write(m_ssl, buf, (int)(m_repeat_length ? m_repeat_length : len)); 00786 if (n == -1) 00787 { 00788 int errnr = SSL_get_error(m_ssl, n); 00789 if ( errnr == SSL_ERROR_WANT_READ || errnr == SSL_ERROR_WANT_WRITE ) 00790 { 00791 m_repeat_length = m_repeat_length ? m_repeat_length : len; 00792 } 00793 else 00794 { 00795 OnDisconnect(); 00796 OnDisconnect(TCP_DISCONNECT_WRITE|TCP_DISCONNECT_ERROR|TCP_DISCONNECT_SSL, errnr); 00797 SetCloseAndDelete(true); 00798 SetFlushBeforeClose(false); 00799 SetLost(); 00800 { 00801 char errbuf[256]; 00802 ERR_error_string_n(errnr, errbuf, 256); 00803 Handler().LogError(this, "OnWrite/SSL_write", errnr, errbuf, LOG_LEVEL_FATAL); 00804 } 00805 } 00806 return 0; 00807 } 00808 else 00809 if (!n) 00810 { 00811 OnDisconnect(); 00812 OnDisconnect(TCP_DISCONNECT_WRITE|TCP_DISCONNECT_SSL, 0); 00813 SetCloseAndDelete(true); 00814 SetFlushBeforeClose(false); 00815 SetLost(); 00816 } 00817 m_repeat_length = 0; 00818 } 00819 else 00820 #endif // HAVE_OPENSSL 00821 { 00822 n = send(GetSocket(), buf, (int)len, MSG_NOSIGNAL); 00823 if (n == -1) 00824 { 00825 // normal error codes: 00826 // WSAEWOULDBLOCK 00827 // EAGAIN or EWOULDBLOCK 00828 #ifdef _WIN32 00829 if (Errno != WSAEWOULDBLOCK) 00830 #else 00831 if (Errno != EWOULDBLOCK) 00832 #endif 00833 { 00834 Handler().LogError(this, "send", Errno, StrError(Errno), LOG_LEVEL_FATAL); 00835 OnDisconnect(); 00836 OnDisconnect(TCP_DISCONNECT_WRITE|TCP_DISCONNECT_ERROR, Errno); 00837 SetCloseAndDelete(true); 00838 SetFlushBeforeClose(false); 00839 SetLost(); 00840 } 00841 return 0; 00842 } 00843 } 00844 if (n > 0) 00845 { 00846 m_bytes_sent += n; 00847 if (GetTrafficMonitor()) 00848 { 00849 GetTrafficMonitor() -> fwrite(buf, 1, n); 00850 } 00851 } 00852 return n; 00853 }
void TcpSocket::Buffer | ( | const char * | buf, | |
size_t | len | |||
) | [private] |
add data to output buffer top
Definition at line 856 of file TcpSocket.cpp.
References m_obuf, m_obuf_top, and m_output_length.
Referenced by SendBuf().
00857 { 00858 size_t ptr = 0; 00859 m_output_length += len; 00860 while (ptr < len) 00861 { 00862 // buf/len => pbuf/sz 00863 size_t space = 0; 00864 if ((space = m_obuf_top ? m_obuf_top -> Space() : 0) > 0) 00865 { 00866 const char *pbuf = buf + ptr; 00867 size_t sz = len - ptr; 00868 if (space >= sz) 00869 { 00870 m_obuf_top -> Add(pbuf, sz); 00871 ptr += sz; 00872 } 00873 else 00874 { 00875 m_obuf_top -> Add(pbuf, space); 00876 ptr += space; 00877 } 00878 } 00879 else 00880 { 00881 m_obuf_top = new OUTPUT; 00882 m_obuf.push_back( m_obuf_top ); 00883 } 00884 } 00885 }
CircularBuffer TcpSocket::ibuf [protected] |
Circular input buffer.
Definition at line 302 of file TcpSocket.h.
Referenced by GetInputLength(), OnRead(), OnSocks4Read(), and ReadInput().
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 318 of file TcpSocket.h.
Referenced by OnRead().
char TcpSocket::m_c [private] |
First char in CRLF or LFCR sequence.
Definition at line 319 of file TcpSocket.h.
Referenced by OnRead().
std::vector<char> TcpSocket::m_line [private] |
Current line in line protocol mode.
Reimplemented in HTTPSocket.
Definition at line 320 of file TcpSocket.h.
size_t TcpSocket::m_line_ptr [private] |
char* TcpSocket::m_buf [private] |
temporary read buffer
Definition at line 323 of file TcpSocket.h.
Referenced by OnRead(), and ~TcpSocket().
output_l TcpSocket::m_obuf [private] |
output buffer
Definition at line 325 of file TcpSocket.h.
Referenced by Buffer(), SendBuf(), SendFromOutputBuffer(), and ~TcpSocket().
OUTPUT* TcpSocket::m_obuf_top [private] |
output buffer on top
Definition at line 326 of file TcpSocket.h.
Referenced by Buffer(), SendBuf(), and SendFromOutputBuffer().
size_t TcpSocket::m_transfer_limit [private] |
Definition at line 327 of file TcpSocket.h.
Referenced by SendFromOutputBuffer(), and SetTransferLimit().
size_t TcpSocket::m_output_length [private] |
Definition at line 328 of file TcpSocket.h.
Referenced by Buffer(), GetOutputLength(), and SendFromOutputBuffer().
size_t TcpSocket::m_repeat_length [private] |
SSLInitializer TcpSocket::m_ssl_init [static, private] |
Definition at line 332 of file TcpSocket.h.
SSL_CTX* TcpSocket::m_ssl_ctx [private] |
ssl context
Definition at line 333 of file TcpSocket.h.
Referenced by GetSslContext(), InitializeContext(), OnSSLAccept(), OnSSLConnect(), and UseCertificateChainFile().
SSL* TcpSocket::m_ssl [private] |
ssl 'socket'
Definition at line 334 of file TcpSocket.h.
Referenced by Close(), GetSsl(), OnRead(), OnSSLAccept(), OnSSLConnect(), SSLNegotiate(), TryWrite(), and ~TcpSocket().
BIO* TcpSocket::m_sbio [private] |
ssl bio
Definition at line 335 of file TcpSocket.h.
Referenced by OnSSLAccept(), and OnSSLConnect().
std::string TcpSocket::m_password [private] |
ssl password
Definition at line 336 of file TcpSocket.h.
Referenced by GetPassword(), and InitializeContext().
Mutex TcpSocket::m_server_ssl_mutex [static, private] |
std::map< std::string, SSL_CTX * > TcpSocket::m_client_contexts [static, private] |
std::map< std::string, SSL_CTX * > TcpSocket::m_server_contexts [static, private] |
int TcpSocket::m_socks4_state [private] |
socks4 support
Definition at line 343 of file TcpSocket.h.
Referenced by OnSocks4Connect(), and OnSocks4Read().
char TcpSocket::m_socks4_vn [private] |
socks4 support, temporary variable
Definition at line 344 of file TcpSocket.h.
Referenced by OnSocks4Read().
char TcpSocket::m_socks4_cd [private] |
socks4 support, temporary variable
Definition at line 345 of file TcpSocket.h.
Referenced by OnSocks4Read().
unsigned short TcpSocket::m_socks4_dstport [private] |
unsigned long TcpSocket::m_socks4_dstip [private] |
int TcpSocket::m_resolver_id [private] |
Resolver id (if any) for current Open call.
Definition at line 351 of file TcpSocket.h.
Referenced by OnResolved(), and Open().
bool TcpSocket::m_b_reconnect [private] |
Reconnect on lost connection flag.
Definition at line 355 of file TcpSocket.h.
Referenced by Reconnect(), and SetReconnect().
bool TcpSocket::m_b_is_reconnect [private] |
Trying to reconnect.
Definition at line 356 of file TcpSocket.h.
Referenced by IsReconnect(), and SetIsReconnect().