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