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 82 of file TcpSocket.cpp.
00082 : StreamSocket(h) 00083 ,ibuf(TCP_BUFSIZE_READ) 00084 ,m_b_input_buffer_disabled(false) 00085 ,m_bytes_sent(0) 00086 ,m_bytes_received(0) 00087 ,m_skip_c(false) 00088 ,m_line(Handler().MaxTcpLineSize()) 00089 ,m_line_ptr(0) 00090 #ifdef SOCKETS_DYNAMIC_TEMP 00091 ,m_buf(new char[TCP_BUFSIZE_READ + 1]) 00092 #endif 00093 ,m_obuf_top(NULL) 00094 ,m_transfer_limit(0) 00095 ,m_output_length(0) 00096 ,m_repeat_length(0) 00097 #ifdef HAVE_OPENSSL 00098 ,m_ssl_ctx(NULL) 00099 ,m_ssl(NULL) 00100 ,m_sbio(NULL) 00101 #endif 00102 #ifdef ENABLE_SOCKS4 00103 ,m_socks4_state(0) 00104 #endif 00105 #ifdef ENABLE_RESOLVER 00106 ,m_resolver_id(0) 00107 #endif 00108 #ifdef ENABLE_RECONNECT 00109 ,m_b_reconnect(false) 00110 ,m_b_is_reconnect(false) 00111 #endif 00112 { 00113 }
| TcpSocket::TcpSocket | ( | ISocketHandler & | h, | |
| size_t | isize, | |||
| size_t | osize | |||
| ) |
Constructor with custom values for i/o buffer.
| h | ISocketHandler reference | |
| isize | Input buffer size | |
| osize | Output buffer size |
Definition at line 122 of file TcpSocket.cpp.
00122 : StreamSocket(h) 00123 ,ibuf(isize) 00124 ,m_b_input_buffer_disabled(false) 00125 ,m_bytes_sent(0) 00126 ,m_bytes_received(0) 00127 ,m_skip_c(false) 00128 ,m_line(Handler().MaxTcpLineSize()) 00129 ,m_line_ptr(0) 00130 #ifdef SOCKETS_DYNAMIC_TEMP 00131 ,m_buf(new char[TCP_BUFSIZE_READ + 1]) 00132 #endif 00133 ,m_obuf_top(NULL) 00134 ,m_transfer_limit(0) 00135 ,m_output_length(0) 00136 ,m_repeat_length(0) 00137 #ifdef HAVE_OPENSSL 00138 ,m_ssl_ctx(NULL) 00139 ,m_ssl(NULL) 00140 ,m_sbio(NULL) 00141 #endif 00142 #ifdef ENABLE_SOCKS4 00143 ,m_socks4_state(0) 00144 #endif 00145 #ifdef ENABLE_RESOLVER 00146 ,m_resolver_id(0) 00147 #endif 00148 #ifdef ENABLE_RECONNECT 00149 ,m_b_reconnect(false) 00150 ,m_b_is_reconnect(false) 00151 #endif 00152 { 00153 }
| TcpSocket::~TcpSocket | ( | ) |
Definition at line 159 of file TcpSocket.cpp.
References m_buf, m_obuf, and m_ssl.
00160 { 00161 #ifdef SOCKETS_DYNAMIC_TEMP 00162 delete[] m_buf; 00163 #endif 00164 // %! empty m_obuf 00165 while (m_obuf.size()) 00166 { 00167 output_l::iterator it = m_obuf.begin(); 00168 OUTPUT *p = *it; 00169 delete p; 00170 m_obuf.erase(it); 00171 } 00172 #ifdef HAVE_OPENSSL 00173 if (m_ssl) 00174 { 00175 SSL_free(m_ssl); 00176 } 00177 #endif 00178 }
| TcpSocket::TcpSocket | ( | const TcpSocket & | s | ) | [protected] |
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 181 of file TcpSocket.cpp.
Referenced by HttpGetSocket::HttpGetSocket(), OnResolved(), Open(), HttpPutSocket::Open(), and HttpPostSocket::Open().
00182 { 00183 Ipv4Address ad(ip, port); 00184 Ipv4Address local; 00185 return Open(ad, local, skip_socks); 00186 }
| bool TcpSocket::Open | ( | SocketAddress & | ad, | |
| bool | skip_socks = false | |||
| ) |
Definition at line 200 of file TcpSocket.cpp.
References Open().
00201 { 00202 Ipv4Address bind_ad("0.0.0.0", 0); 00203 return Open(ad, bind_ad, skip_socks); 00204 }
| bool TcpSocket::Open | ( | SocketAddress & | ad, | |
| SocketAddress & | bind_address, | |||
| bool | skip_socks = false | |||
| ) |
Definition at line 207 of file TcpSocket.cpp.
References Socket::Attach(), closesocket, Socket::CopyConnection(), Socket::CreateSocket(), Errno, ISocketHandler::FindConnection(), SocketAddress::GetFamily(), SocketAddress::GetPort(), Socket::GetSocks4Host(), Socket::GetSocks4Port(), Socket::Handler(), INVALID_SOCKET, SocketAddress::IsValid(), Utility::l2ip(), Utility::l2string(), LOG_LEVEL_FATAL, LOG_LEVEL_INFO, ISocketHandler::LogError(), Open(), Reconnect(), Socket::SetCallOnConnect(), Socket::SetClientRemoteAddress(), Socket::SetCloseAndDelete(), StreamSocket::SetConnecting(), Socket::SetIsClient(), Socket::SetNonblocking(), Socket::SetRemoteAddress(), Socket::SetSocks4(), Socket::Socks4(), and StrError.
00208 { 00209 if (!ad.IsValid()) 00210 { 00211 Handler().LogError(this, "Open", 0, "Invalid SocketAddress", LOG_LEVEL_FATAL); 00212 SetCloseAndDelete(); 00213 return false; 00214 } 00215 if (Handler().GetCount() >= Handler().MaxCount()) 00216 { 00217 Handler().LogError(this, "Open", 0, "no space left for more sockets", LOG_LEVEL_FATAL); 00218 SetCloseAndDelete(); 00219 return false; 00220 } 00221 SetConnecting(false); 00222 #ifdef ENABLE_SOCKS4 00223 SetSocks4(false); 00224 #endif 00225 // check for pooling 00226 #ifdef ENABLE_POOL 00227 if (Handler().PoolEnabled()) 00228 { 00229 ISocketHandler::PoolSocket *pools = Handler().FindConnection(SOCK_STREAM, "tcp", ad); 00230 if (pools) 00231 { 00232 CopyConnection( pools ); 00233 delete pools; 00234 00235 SetIsClient(); 00236 SetCallOnConnect(); // ISocketHandler must call OnConnect 00237 Handler().LogError(this, "SetCallOnConnect", 0, "Found pooled connection", LOG_LEVEL_INFO); 00238 return true; 00239 } 00240 } 00241 #endif 00242 // if not, create new connection 00243 SOCKET s = CreateSocket(ad.GetFamily(), SOCK_STREAM, "tcp"); 00244 if (s == INVALID_SOCKET) 00245 { 00246 return false; 00247 } 00248 // socket must be nonblocking for async connect 00249 if (!SetNonblocking(true, s)) 00250 { 00251 SetCloseAndDelete(); 00252 closesocket(s); 00253 return false; 00254 } 00255 #ifdef ENABLE_POOL 00256 SetIsClient(); // client because we connect 00257 #endif 00258 SetClientRemoteAddress(ad); 00259 int n = 0; 00260 if (bind_ad.GetPort() != 0) 00261 { 00262 bind(s, bind_ad, bind_ad); 00263 } 00264 #ifdef ENABLE_SOCKS4 00265 if (!skip_socks && GetSocks4Host() && GetSocks4Port()) 00266 { 00267 Ipv4Address sa(GetSocks4Host(), GetSocks4Port()); 00268 { 00269 std::string sockshost; 00270 Utility::l2ip(GetSocks4Host(), sockshost); 00271 Handler().LogError(this, "Open", 0, "Connecting to socks4 server @ " + sockshost + ":" + 00272 Utility::l2string(GetSocks4Port()), LOG_LEVEL_INFO); 00273 } 00274 SetSocks4(); 00275 n = connect(s, sa, sa); 00276 SetRemoteAddress(sa); 00277 } 00278 else 00279 #endif 00280 { 00281 n = connect(s, ad, ad); 00282 SetRemoteAddress(ad); 00283 } 00284 if (n == -1) 00285 { 00286 // check error code that means a connect is in progress 00287 #ifdef _WIN32 00288 if (Errno == WSAEWOULDBLOCK) 00289 #else 00290 if (Errno == EINPROGRESS) 00291 #endif 00292 { 00293 Attach(s); 00294 SetConnecting( true ); // this flag will control fd_set's 00295 } 00296 else 00297 #ifdef ENABLE_SOCKS4 00298 if (Socks4() && Handler().Socks4TryDirect() ) // retry 00299 { 00300 closesocket(s); 00301 return Open(ad, true); 00302 } 00303 else 00304 #endif 00305 #ifdef ENABLE_RECONNECT 00306 if (Reconnect()) 00307 { 00308 Handler().LogError(this, "connect: failed, reconnect pending", Errno, StrError(Errno), LOG_LEVEL_INFO); 00309 Attach(s); 00310 SetConnecting( true ); // this flag will control fd_set's 00311 } 00312 else 00313 #endif 00314 { 00315 Handler().LogError(this, "connect: failed", Errno, StrError(Errno), LOG_LEVEL_FATAL); 00316 SetCloseAndDelete(); 00317 closesocket(s); 00318 return false; 00319 } 00320 } 00321 else 00322 { 00323 Attach(s); 00324 SetCallOnConnect(); // ISocketHandler must call OnConnect 00325 } 00326 00327 // 'true' means connected or connecting(not yet connected) 00328 // 'false' means something failed 00329 return true; 00330 }
| bool TcpSocket::Open | ( | const std::string & | host, | |
| port_t | port | |||
| ) |
Open connection.
| host | Hostname | |
| port | Port number |
Definition at line 333 of file TcpSocket.cpp.
References Socket::Handler(), Utility::isipv4(), Utility::isipv6(), m_resolver_id, Open(), Socket::Resolve(), Socket::SetCloseAndDelete(), and Utility::u2ip().
00334 { 00335 #ifdef ENABLE_IPV6 00336 #ifdef IPPROTO_IPV6 00337 if (IsIpv6()) 00338 { 00339 #ifdef ENABLE_RESOLVER 00340 if (!Handler().ResolverEnabled() || Utility::isipv6(host) ) 00341 { 00342 #endif 00343 in6_addr a; 00344 if (!Utility::u2ip(host, a)) 00345 { 00346 SetCloseAndDelete(); 00347 return false; 00348 } 00349 Ipv6Address ad(a, port); 00350 Ipv6Address local; 00351 return Open(ad, local); 00352 #ifdef ENABLE_RESOLVER 00353 } 00354 m_resolver_id = Resolve6(host, port); 00355 return true; 00356 #endif 00357 } 00358 #endif 00359 #endif 00360 #ifdef ENABLE_RESOLVER 00361 if (!Handler().ResolverEnabled() || Utility::isipv4(host) ) 00362 { 00363 #endif 00364 ipaddr_t l; 00365 if (!Utility::u2ip(host,l)) 00366 { 00367 SetCloseAndDelete(); 00368 return false; 00369 } 00370 Ipv4Address ad(l, port); 00371 Ipv4Address local; 00372 return Open(ad, local); 00373 #ifdef ENABLE_RESOLVER 00374 } 00375 // resolve using async resolver thread 00376 m_resolver_id = Resolve(host, port); 00377 return true; 00378 #endif 00379 }
| void TcpSocket::OnConnectTimeout | ( | ) | [virtual] |
Connect timeout callback.
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 884 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().
00885 { 00886 SendBuf(str.c_str(),str.size(),i); 00887 }
| void TcpSocket::Sendf | ( | const char * | format, | |
| ... | ||||
| ) |
Send string using printf formatting.
Definition at line 1079 of file TcpSocket.cpp.
References Send().
Referenced by HttpDebugSocket::OnFirst().
01080 { 01081 va_list ap; 01082 va_start(ap, format); 01083 char slask[5000]; // vsprintf / vsnprintf temporary 01084 vsnprintf(slask, sizeof(slask), format, ap); 01085 va_end(ap); 01086 Send( slask ); 01087 }
| 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 890 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(), HttpPutSocket::OnConnect(), HttpDebugSocket::OnData(), OnSocks4Connect(), HttpBaseSocket::OnTransferLimit(), Ajp13Socket::OnTransferLimit(), Ajp13Socket::ReceiveBody(), Ajp13Socket::Respond(), Send(), and HttpdSocket::Send64().
00891 { 00892 if (!Ready() && !Connecting()) 00893 { 00894 Handler().LogError(this, "SendBuf", -1, "Attempt to write to a non-ready socket" ); // warning 00895 if (GetSocket() == INVALID_SOCKET) 00896 Handler().LogError(this, "SendBuf", 0, " * GetSocket() == INVALID_SOCKET", LOG_LEVEL_INFO); 00897 if (Connecting()) 00898 Handler().LogError(this, "SendBuf", 0, " * Connecting()", LOG_LEVEL_INFO); 00899 if (CloseAndDelete()) 00900 Handler().LogError(this, "SendBuf", 0, " * CloseAndDelete()", LOG_LEVEL_INFO); 00901 return; 00902 } 00903 if (!IsConnected()) 00904 { 00905 Handler().LogError(this, "SendBuf", -1, "Attempt to write to a non-connected socket, will be sent on connect" ); // warning 00906 Buffer(buf, len); 00907 return; 00908 } 00909 if (m_obuf_top) 00910 { 00911 Buffer(buf, len); 00912 return; 00913 } 00914 #ifdef HAVE_OPENSSL 00915 if (IsSSL()) 00916 { 00917 Buffer(buf, len); 00918 SendFromOutputBuffer(); 00919 return; 00920 } 00921 #endif 00922 int n = TryWrite(buf, len); 00923 if (n >= 0 && n < (int)len) 00924 { 00925 Buffer(buf + n, len - n); 00926 } 00927 // if ( data in buffer || !IsConnected ) 00928 // { 00929 // add to buffer 00930 // } 00931 // else 00932 // try_send 00933 // if any data is unsent, buffer it and set m_wfds 00934 00935 // check output buffer set, set/reset m_wfds accordingly 00936 { 00937 bool br = !IsDisableRead(); 00938 if (m_obuf.size()) 00939 Handler().ISocketHandler_Mod(this, br, true); 00940 else 00941 Handler().ISocketHandler_Mod(this, br, false); 00942 } 00943 }
| 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 668 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 946 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 965 of file TcpSocket.cpp.
References Socket::GetClientRemoteAddress(), Socket::GetSocks4Userid(), m_socks4_state, and SendBuf().
00966 { 00967 char request[1000]; 00968 memset(request, 0, sizeof(request)); 00969 request[0] = 4; // socks v4 00970 request[1] = 1; // command code: CONNECT 00971 { 00972 std::auto_ptr<SocketAddress> ad = GetClientRemoteAddress(); 00973 if (ad.get()) 00974 { 00975 struct sockaddr *p0 = (struct sockaddr *)*ad; 00976 struct sockaddr_in *p = (struct sockaddr_in *)p0; 00977 if (p -> sin_family == AF_INET) 00978 { 00979 memcpy(request + 2, &p -> sin_port, 2); // nwbo is ok here 00980 memcpy(request + 4, &p -> sin_addr, sizeof(struct in_addr)); 00981 } 00982 else 00983 { 00985 } 00986 } 00987 else 00988 { 00990 } 00991 } 00992 #if defined( _WIN32) && !defined(__CYGWIN__) 00993 strcpy_s(request + 8, sizeof(request) - 8, GetSocks4Userid().c_str()); 00994 #else 00995 strcpy(request + 8, GetSocks4Userid().c_str()); 00996 #endif 00997 size_t length = GetSocks4Userid().size() + 8 + 1; 00998 SendBuf(request, length); 00999 m_socks4_state = 0; 01000 }
| void TcpSocket::OnSocks4ConnectFailed | ( | ) | [virtual] |
Socks4 specific callback.
Reimplemented from Socket.
Definition at line 1003 of file TcpSocket.cpp.
References Socket::Handler(), LOG_LEVEL_WARNING, ISocketHandler::LogError(), Socket::OnConnectFailed(), Socket::SetCloseAndDelete(), StreamSocket::SetConnecting(), and Socket::SetRetryClientConnect().
Referenced by OnConnectTimeout(), and OnWrite().
01004 { 01005 Handler().LogError(this,"OnSocks4ConnectFailed",0,"connection to socks4 server failed, trying direct connection",LOG_LEVEL_WARNING); 01006 if (!Handler().Socks4TryDirect()) 01007 { 01008 SetConnecting(false); 01009 SetCloseAndDelete(); 01010 OnConnectFailed(); // just in case 01011 } 01012 else 01013 { 01014 SetRetryClientConnect(); 01015 } 01016 }
| bool TcpSocket::OnSocks4Read | ( | ) | [virtual] |
Socks4 specific callback.
Reimplemented from Socket.
Definition at line 1019 of file TcpSocket.cpp.
References GetInputLength(), Socket::Handler(), ibuf, LOG_LEVEL_FATAL, LOG_LEVEL_INFO, ISocketHandler::LogError(), m_socks4_cd, m_socks4_dstip, m_socks4_dstport, m_socks4_state, m_socks4_vn, Socket::OnConnect(), Socket::OnConnectFailed(), TcpSocket::CircularBuffer::Read(), Socket::SetCloseAndDelete(), StreamSocket::SetConnecting(), and Socket::SetSocks4().
Referenced by OnRead().
01020 { 01021 switch (m_socks4_state) 01022 { 01023 case 0: 01024 ibuf.Read(&m_socks4_vn, 1); 01025 m_socks4_state = 1; 01026 break; 01027 case 1: 01028 ibuf.Read(&m_socks4_cd, 1); 01029 m_socks4_state = 2; 01030 break; 01031 case 2: 01032 if (GetInputLength() > 1) 01033 { 01034 ibuf.Read( (char *)&m_socks4_dstport, 2); 01035 m_socks4_state = 3; 01036 } 01037 else 01038 { 01039 return true; 01040 } 01041 break; 01042 case 3: 01043 if (GetInputLength() > 3) 01044 { 01045 ibuf.Read( (char *)&m_socks4_dstip, 4); 01046 SetSocks4(false); 01047 01048 switch (m_socks4_cd) 01049 { 01050 case 90: 01051 OnConnect(); 01052 Handler().LogError(this, "OnSocks4Read", 0, "Connection established", LOG_LEVEL_INFO); 01053 break; 01054 case 91: 01055 case 92: 01056 case 93: 01057 Handler().LogError(this,"OnSocks4Read",m_socks4_cd,"socks4 server reports connect failed",LOG_LEVEL_FATAL); 01058 SetConnecting(false); 01059 SetCloseAndDelete(); 01060 OnConnectFailed(); 01061 break; 01062 default: 01063 Handler().LogError(this,"OnSocks4Read",m_socks4_cd,"socks4 server unrecognized response",LOG_LEVEL_FATAL); 01064 SetCloseAndDelete(); 01065 break; 01066 } 01067 } 01068 else 01069 { 01070 return true; 01071 } 01072 break; 01073 } 01074 return false; 01075 }
Callback executed when resolver thread has finished a resolve request.
Reimplemented from Socket.
Definition at line 383 of file TcpSocket.cpp.
References ISocketHandler::Add(), DEB, Socket::Handler(), LOG_LEVEL_FATAL, ISocketHandler::LogError(), m_resolver_id, Open(), and Socket::SetCloseAndDelete().
Referenced by ResolvSocket::OnLine().
00384 { 00385 DEB( fprintf(stderr, "TcpSocket::OnResolved id %d addr %x port %d\n", id, a, port);) 00386 if (id == m_resolver_id) 00387 { 00388 if (a && port) 00389 { 00390 Ipv4Address ad(a, port); 00391 Ipv4Address local; 00392 if (Open(ad, local)) 00393 { 00394 if (!Handler().Valid(this)) 00395 { 00396 Handler().Add(this); 00397 } 00398 } 00399 } 00400 else 00401 { 00402 Handler().LogError(this, "OnResolved", 0, "Resolver failed", LOG_LEVEL_FATAL); 00403 SetCloseAndDelete(); 00404 } 00405 } 00406 else 00407 { 00408 Handler().LogError(this, "OnResolved", id, "Resolver returned wrong job id", LOG_LEVEL_FATAL); 00409 SetCloseAndDelete(); 00410 } 00411 }
| void TcpSocket::OnSSLConnect | ( | ) | [virtual] |
Callback for 'New' ssl support - replaces SSLSocket.
Internal use.
Reimplemented from Socket.
Definition at line 1091 of file TcpSocket.cpp.
References DEB, Socket::GetSocket(), InitSSLClient(), m_sbio, m_ssl, m_ssl_ctx, Socket::SetCloseAndDelete(), Socket::SetNonblocking(), Socket::SetSSLNegotiate(), and SSLNegotiate().
01092 { 01093 SetNonblocking(true); 01094 { 01095 if (m_ssl_ctx) 01096 { 01097 DEB( fprintf(stderr, "SSL Context already initialized - closing socket\n");) 01098 SetCloseAndDelete(true); 01099 return; 01100 } 01101 InitSSLClient(); 01102 } 01103 if (m_ssl_ctx) 01104 { 01105 /* Connect the SSL socket */ 01106 m_ssl = SSL_new(m_ssl_ctx); 01107 if (!m_ssl) 01108 { 01109 DEB( fprintf(stderr, " m_ssl is NULL\n");) 01110 SetCloseAndDelete(true); 01111 return; 01112 } 01113 m_sbio = BIO_new_socket((int)GetSocket(), BIO_NOCLOSE); 01114 if (!m_sbio) 01115 { 01116 DEB( fprintf(stderr, " m_sbio is NULL\n");) 01117 SetCloseAndDelete(true); 01118 return; 01119 } 01120 SSL_set_bio(m_ssl, m_sbio, m_sbio); 01121 if (!SSLNegotiate()) 01122 { 01123 SetSSLNegotiate(); 01124 } 01125 } 01126 else 01127 { 01128 SetCloseAndDelete(); 01129 } 01130 }
| void TcpSocket::OnSSLAccept | ( | ) | [virtual] |
Callback for 'New' ssl support - replaces SSLSocket.
Internal use.
Reimplemented from Socket.
Definition at line 1133 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().
01134 { 01135 SetNonblocking(true); 01136 { 01137 if (m_ssl_ctx) 01138 { 01139 DEB( fprintf(stderr, "SSL Context already initialized - closing socket\n");) 01140 SetCloseAndDelete(true); 01141 return; 01142 } 01143 InitSSLServer(); 01144 SetSSLServer(); 01145 } 01146 if (m_ssl_ctx) 01147 { 01148 m_ssl = SSL_new(m_ssl_ctx); 01149 if (!m_ssl) 01150 { 01151 DEB( fprintf(stderr, " m_ssl is NULL\n");) 01152 SetCloseAndDelete(true); 01153 return; 01154 } 01155 m_sbio = BIO_new_socket((int)GetSocket(), BIO_NOCLOSE); 01156 if (!m_sbio) 01157 { 01158 DEB( fprintf(stderr, " m_sbio is NULL\n");) 01159 SetCloseAndDelete(true); 01160 return; 01161 } 01162 SSL_set_bio(m_ssl, m_sbio, m_sbio); 01163 // if (!SSLNegotiate()) 01164 { 01165 SetSSLNegotiate(); 01166 } 01167 } 01168 }
| void TcpSocket::InitSSLClient | ( | ) | [virtual] |
This method must be implemented to initialize the ssl context for an outgoing connection.
Definition at line 1262 of file TcpSocket.cpp.
References InitializeContext().
Referenced by OnSSLConnect().
01263 { 01264 InitializeContext("", SSLv23_method()); 01265 }
| void TcpSocket::InitSSLServer | ( | ) | [virtual] |
This method must be implemented to initialize the ssl context for an incoming connection.
Definition at line 1268 of file TcpSocket.cpp.
References Socket::Handler(), LOG_LEVEL_FATAL, ISocketHandler::LogError(), and Socket::SetCloseAndDelete().
Referenced by OnSSLAccept().
01269 { 01270 Handler().LogError(this, "InitSSLServer", 0, "You MUST implement your own InitSSLServer method", LOG_LEVEL_FATAL); 01271 SetCloseAndDelete(); 01272 }
| 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 442 of file TcpSocket.cpp.
References DEB, Errno, Socket::GetSocket(), Socket::GetTrafficMonitor(), Socket::Handler(), ibuf, Socket::IsSSL(), LOG_LEVEL_ERROR, LOG_LEVEL_FATAL, LOG_LEVEL_WARNING, ISocketHandler::LogError(), m_b_input_buffer_disabled, m_buf, m_bytes_received, m_ssl, Socket::OnDisconnect(), StreamSocket::Ready(), Socket::SetCloseAndDelete(), StreamSocket::SetFlushBeforeClose(), Socket::SetLost(), StreamSocket::SetShutdown(), StrError, TCP_BUFSIZE_READ, TCP_DISCONNECT_ERROR, TCP_DISCONNECT_SSL, and TcpSocket::CircularBuffer::Write().
Referenced by HTTPSocket::OnRawData().
00443 { 00444 int n = 0; 00445 #ifdef SOCKETS_DYNAMIC_TEMP 00446 char *buf = m_buf; 00447 #else 00448 char buf[TCP_BUFSIZE_READ]; 00449 #endif 00450 #ifdef HAVE_OPENSSL 00451 if (IsSSL()) 00452 { 00453 if (!Ready()) 00454 return; 00455 n = SSL_read(m_ssl, buf, TCP_BUFSIZE_READ); 00456 if (n == -1) 00457 { 00458 n = SSL_get_error(m_ssl, n); 00459 switch (n) 00460 { 00461 case SSL_ERROR_NONE: 00462 case SSL_ERROR_WANT_READ: 00463 case SSL_ERROR_WANT_WRITE: 00464 break; 00465 case SSL_ERROR_ZERO_RETURN: 00466 DEB( fprintf(stderr, "SSL_read() returns zero - closing socket\n");) 00467 OnDisconnect(); 00468 OnDisconnect(TCP_DISCONNECT_SSL|TCP_DISCONNECT_ERROR, n); 00469 SetCloseAndDelete(true); 00470 SetFlushBeforeClose(false); 00471 SetLost(); 00472 break; 00473 default: 00474 DEB( fprintf(stderr, "SSL read problem, errcode = %d\n",n);) 00475 OnDisconnect(); 00476 OnDisconnect(TCP_DISCONNECT_SSL|TCP_DISCONNECT_ERROR, n); 00477 SetCloseAndDelete(true); 00478 SetFlushBeforeClose(false); 00479 SetLost(); 00480 } 00481 return; 00482 } 00483 else 00484 if (!n) 00485 { 00486 DEB( n = SSL_get_error(m_ssl, n); 00487 fprintf(stderr, "SSL_read returns 0, SSL_get_error: %d\n", n); 00488 if (n == SSL_ERROR_SYSCALL) 00489 { 00490 fprintf(stderr, "ERR_get_error() returns %ld\n", ERR_get_error()); 00491 perror("errno: SSL_read"); 00492 }) 00493 OnDisconnect(); 00494 OnDisconnect(TCP_DISCONNECT_SSL, 0); 00495 SetCloseAndDelete(true); 00496 SetFlushBeforeClose(false); 00497 SetLost(); 00498 SetShutdown(SHUT_WR); 00499 return; 00500 } 00501 else 00502 if (n > 0 && n <= TCP_BUFSIZE_READ) 00503 { 00504 m_bytes_received += n; 00505 if (GetTrafficMonitor()) 00506 { 00507 GetTrafficMonitor() -> fwrite(buf, 1, n); 00508 } 00509 if (!m_b_input_buffer_disabled && !ibuf.Write(buf,n)) 00510 { 00511 Handler().LogError(this, "OnRead(ssl)", 0, "ibuf overflow", LOG_LEVEL_WARNING); 00512 } 00513 } 00514 else 00515 { 00516 Handler().LogError(this, "OnRead(ssl)", n, "abnormal value from SSL_read", LOG_LEVEL_ERROR); 00517 } 00518 } 00519 else 00520 #endif // HAVE_OPENSSL 00521 { 00522 n = recv(GetSocket(), buf, TCP_BUFSIZE_READ, MSG_NOSIGNAL); 00523 if (n == -1) 00524 { 00525 Handler().LogError(this, "read", Errno, StrError(Errno), LOG_LEVEL_FATAL); 00526 OnDisconnect(); 00527 OnDisconnect(TCP_DISCONNECT_ERROR, Errno); 00528 SetCloseAndDelete(true); 00529 SetFlushBeforeClose(false); 00530 SetLost(); 00531 return; 00532 } 00533 else 00534 if (!n) 00535 { 00536 OnDisconnect(); 00537 OnDisconnect(0, 0); 00538 SetCloseAndDelete(true); 00539 SetFlushBeforeClose(false); 00540 SetLost(); 00541 SetShutdown(SHUT_WR); 00542 return; 00543 } 00544 else 00545 if (n > 0 && n <= TCP_BUFSIZE_READ) 00546 { 00547 m_bytes_received += n; 00548 if (GetTrafficMonitor()) 00549 { 00550 GetTrafficMonitor() -> fwrite(buf, 1, n); 00551 } 00552 if (!m_b_input_buffer_disabled && !ibuf.Write(buf,n)) 00553 { 00554 Handler().LogError(this, "OnRead", 0, "ibuf overflow", LOG_LEVEL_WARNING); 00555 } 00556 } 00557 else 00558 { 00559 Handler().LogError(this, "OnRead", n, "abnormal value from recv", LOG_LEVEL_ERROR); 00560 } 00561 } 00562 // 00563 OnRead( buf, n ); 00564 }
| void TcpSocket::OnRead | ( | char * | buf, | |
| size_t | n | |||
| ) | [protected] |
Definition at line 567 of file TcpSocket.cpp.
References Socket::CloseAndDelete(), GetInputLength(), Socket::Handler(), StreamSocket::LineProtocol(), LOG_LEVEL_FATAL, ISocketHandler::LogError(), m_b_input_buffer_disabled, m_c, m_line, m_line_ptr, m_skip_c, OnLine(), OnRawData(), OnSocks4Read(), Socket::SetCloseAndDelete(), Socket::Socks4(), and TCP_BUFSIZE_READ.
00568 { 00569 // unbuffered 00570 if (n > 0 && n <= TCP_BUFSIZE_READ) 00571 { 00572 if (LineProtocol()) 00573 { 00574 buf[n] = 0; 00575 size_t i = 0; 00576 if (m_skip_c && (buf[i] == 13 || buf[i] == 10) && buf[i] != m_c) 00577 { 00578 m_skip_c = false; 00579 i++; 00580 } 00581 size_t x = i; 00582 for (; i < n && LineProtocol(); i++) 00583 { 00584 while ((buf[i] == 13 || buf[i] == 10) && LineProtocol()) 00585 { 00586 char c = buf[i]; 00587 buf[i] = 0; 00588 if (buf[x]) 00589 { 00590 size_t sz = strlen(&buf[x]); 00591 if (m_line_ptr + sz < Handler().MaxTcpLineSize()) 00592 { 00593 memcpy(&m_line[m_line_ptr], &buf[x], sz); 00594 m_line_ptr += sz; 00595 } 00596 else 00597 { 00598 Handler().LogError(this, "TcpSocket::OnRead", (int)(m_line_ptr + sz), "maximum tcp_line_size exceeded, connection closed", LOG_LEVEL_FATAL); 00599 SetCloseAndDelete(); 00600 } 00601 } 00602 if (m_line_ptr > 0) 00603 OnLine( std::string(&m_line[0], m_line_ptr) ); 00604 else 00605 OnLine( "" ); 00606 i++; 00607 m_skip_c = true; 00608 m_c = c; 00609 if (i < n && (buf[i] == 13 || buf[i] == 10) && buf[i] != c) 00610 { 00611 m_skip_c = false; 00612 i++; 00613 } 00614 x = i; 00615 m_line_ptr = 0; 00616 } 00617 if (!LineProtocol()) 00618 { 00619 break; 00620 } 00621 } 00622 if (!LineProtocol()) 00623 { 00624 if (i < n) 00625 { 00626 OnRawData(buf + i, n - i); 00627 } 00628 } 00629 else 00630 if (buf[x]) 00631 { 00632 size_t sz = strlen(&buf[x]); 00633 if (m_line_ptr + sz < Handler().MaxTcpLineSize()) 00634 { 00635 memcpy(&m_line[m_line_ptr], &buf[x], sz); 00636 m_line_ptr += sz; 00637 } 00638 else 00639 { 00640 Handler().LogError(this, "TcpSocket::OnRead", (int)(m_line_ptr + sz), "maximum tcp_line_size exceeded, connection closed", LOG_LEVEL_FATAL); 00641 SetCloseAndDelete(); 00642 } 00643 } 00644 } 00645 else 00646 { 00647 OnRawData(buf, n); 00648 } 00649 } 00650 if (m_b_input_buffer_disabled) 00651 { 00652 return; 00653 } 00654 // further processing: socks4 00655 #ifdef ENABLE_SOCKS4 00656 if (Socks4()) 00657 { 00658 bool need_more = false; 00659 while (GetInputLength() && !need_more && !CloseAndDelete()) 00660 { 00661 need_more = OnSocks4Read(); 00662 } 00663 } 00664 #endif 00665 }
| void TcpSocket::OnWrite | ( | ) | [protected, virtual] |
Called when there is room for another write on the file descriptor.
Reimplemented from Socket.
Definition at line 673 of file TcpSocket.cpp.
References StreamSocket::Connecting(), StreamSocket::GetConnectionRetries(), StreamSocket::GetConnectionRetry(), Socket::Handler(), Socket::IsDisableRead(), 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().
00674 { 00675 if (Connecting()) 00676 { 00677 int err = SoError(); 00678 00679 // don't reset connecting flag on error here, we want the OnConnectFailed timeout later on 00680 if (!err) // ok 00681 { 00682 Handler().ISocketHandler_Mod(this, !IsDisableRead(), false); 00683 SetConnecting(false); 00684 SetCallOnConnect(); 00685 return; 00686 } 00687 Handler().LogError(this, "tcp: connect failed", err, StrError(err), LOG_LEVEL_FATAL); 00688 Handler().ISocketHandler_Mod(this, false, false); // no more monitoring because connection failed 00689 00690 // failed 00691 #ifdef ENABLE_SOCKS4 00692 if (Socks4()) 00693 { 00694 // %! leave 'Connecting' flag set? 00695 OnSocks4ConnectFailed(); 00696 return; 00697 } 00698 #endif 00699 if (GetConnectionRetry() == -1 || 00700 (GetConnectionRetry() && GetConnectionRetries() < GetConnectionRetry()) ) 00701 { 00702 // even though the connection failed at once, only retry after 00703 // the connection timeout. 00704 // should we even try to connect again, when CheckConnect returns 00705 // false it's because of a connection error - not a timeout... 00706 return; 00707 } 00708 SetConnecting(false); 00709 SetCloseAndDelete( true ); 00711 OnConnectFailed(); 00712 return; 00713 } 00714 00715 SendFromOutputBuffer(); 00716 }
| void TcpSocket::InitializeContext | ( | const std::string & | context, | |
| const SSL_METHOD * | meth_in = NULL | |||
| ) | [protected] |
SSL; Initialize ssl context for a client socket.
| meth_in | SSL method |
Definition at line 1275 of file TcpSocket.cpp.
References m_client_contexts, and m_ssl_ctx.
Referenced by InitSSLClient().
01276 { 01277 static Mutex mutex; 01278 Lock lock(mutex); 01279 /* Create our context*/ 01280 if (m_client_contexts.find(context) == m_client_contexts.end()) 01281 { 01282 SSL_METHOD *meth = const_cast<SSL_METHOD *>(meth_in) ? 01283 const_cast<SSL_METHOD *>(meth_in) : const_cast<SSL_METHOD *>(SSLv3_method()); 01284 m_ssl_ctx = m_client_contexts[context] = SSL_CTX_new(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 SSL_METHOD *meth = meth_in ? const_cast<SSL_METHOD *>(meth_in) : SSLv3_method(); 01301 m_ssl_ctx = m_server_contexts[context] = SSL_CTX_new(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 SSL_METHOD *meth = meth_in ? const_cast<SSL_METHOD *>(meth_in) : SSLv3_method(); 01337 m_ssl_ctx = m_server_contexts[context] = SSL_CTX_new(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 1171 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().
01172 { 01173 if (!IsSSLServer()) // client 01174 { 01175 int r = SSL_connect(m_ssl); 01176 if (r > 0) 01177 { 01178 SetSSLNegotiate(false); 01180 // CheckCertificateChain( "");//ServerHOST); 01181 SetConnected(); 01182 if (GetOutputLength()) 01183 { 01184 OnWrite(); 01185 } 01186 #ifdef ENABLE_RECONNECT 01187 if (IsReconnect()) 01188 { 01189 OnReconnect(); 01190 } 01191 else 01192 #endif 01193 { 01194 OnConnect(); 01195 } 01196 Handler().LogError(this, "SSLNegotiate/SSL_connect", 0, "Connection established", LOG_LEVEL_INFO); 01197 return true; 01198 } 01199 else 01200 if (!r) 01201 { 01202 Handler().LogError(this, "SSLNegotiate/SSL_connect", 0, "Connection failed", LOG_LEVEL_INFO); 01203 SetSSLNegotiate(false); 01204 SetCloseAndDelete(); 01205 OnSSLConnectFailed(); 01206 } 01207 else 01208 { 01209 r = SSL_get_error(m_ssl, r); 01210 if (r != SSL_ERROR_WANT_READ && r != SSL_ERROR_WANT_WRITE) 01211 { 01212 Handler().LogError(this, "SSLNegotiate/SSL_connect", -1, "Connection failed", LOG_LEVEL_INFO); 01213 DEB( fprintf(stderr, "SSL_connect() failed - closing socket, return code: %d\n",r);) 01214 SetSSLNegotiate(false); 01215 SetCloseAndDelete(true); 01216 OnSSLConnectFailed(); 01217 } 01218 } 01219 } 01220 else // server 01221 { 01222 int r = SSL_accept(m_ssl); 01223 if (r > 0) 01224 { 01225 SetSSLNegotiate(false); 01227 // CheckCertificateChain( "");//ClientHOST); 01228 SetConnected(); 01229 if (GetOutputLength()) 01230 { 01231 OnWrite(); 01232 } 01233 OnAccept(); 01234 Handler().LogError(this, "SSLNegotiate/SSL_accept", 0, "Connection established", LOG_LEVEL_INFO); 01235 return true; 01236 } 01237 else 01238 if (!r) 01239 { 01240 Handler().LogError(this, "SSLNegotiate/SSL_accept", 0, "Connection failed", LOG_LEVEL_INFO); 01241 SetSSLNegotiate(false); 01242 SetCloseAndDelete(); 01243 OnSSLAcceptFailed(); 01244 } 01245 else 01246 { 01247 r = SSL_get_error(m_ssl, r); 01248 if (r != SSL_ERROR_WANT_READ && r != SSL_ERROR_WANT_WRITE) 01249 { 01250 Handler().LogError(this, "SSLNegotiate/SSL_accept", -1, "Connection failed", LOG_LEVEL_INFO); 01251 DEB( fprintf(stderr, "SSL_accept() failed - closing socket, return code: %d\n",r);) 01252 SetSSLNegotiate(false); 01253 SetCloseAndDelete(true); 01254 OnSSLAcceptFailed(); 01255 } 01256 } 01257 } 01258 return false; 01259 }
| 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 719 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().
00720 { 00721 // try send next block in buffer 00722 // if full block is sent, repeat 00723 // if all blocks are sent, reset m_wfds 00724 00725 bool repeat = false; 00726 size_t sz = m_transfer_limit ? GetOutputLength() : 0; 00727 do 00728 { 00729 if (m_obuf.empty()) 00730 { 00731 Handler().LogError(this, "OnWrite", (int)m_output_length, "Empty output buffer in OnWrite", LOG_LEVEL_ERROR); 00732 break; 00733 } 00734 output_l::iterator it = m_obuf.begin(); 00735 OUTPUT *p = *it; 00736 repeat = false; 00737 int n = TryWrite(p -> Buf(), p -> Len()); 00738 if (n > 0) 00739 { 00740 size_t left = p -> Remove(n); 00741 m_output_length -= n; 00742 if (!left) 00743 { 00744 delete p; 00745 m_obuf.erase(it); 00746 if (!m_obuf.size()) 00747 { 00748 m_obuf_top = NULL; 00749 OnWriteComplete(); 00750 } 00751 else 00752 { 00753 repeat = true; 00754 } 00755 } 00756 } 00757 } while (repeat); 00758 00759 if (m_transfer_limit && sz > m_transfer_limit && GetOutputLength() < m_transfer_limit) 00760 { 00761 OnTransferLimit(); 00762 } 00763 00764 // check output buffer set, set/reset m_wfds accordingly 00765 { 00766 bool br = !IsDisableRead(); 00767 if (m_obuf.size()) 00768 Handler().ISocketHandler_Mod(this, br, true); 00769 else 00770 Handler().ISocketHandler_Mod(this, br, false); 00771 } 00772 }
| int TcpSocket::TryWrite | ( | const char * | buf, | |
| size_t | len | |||
| ) | [private] |
the actual send()
Definition at line 775 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().
00776 { 00777 int n = 0; 00778 #ifdef HAVE_OPENSSL 00779 if (IsSSL()) 00780 { 00781 n = SSL_write(m_ssl, buf, (int)(m_repeat_length ? m_repeat_length : len)); 00782 if (n == -1) 00783 { 00784 int errnr = SSL_get_error(m_ssl, n); 00785 if ( errnr == SSL_ERROR_WANT_READ || errnr == SSL_ERROR_WANT_WRITE ) 00786 { 00787 m_repeat_length = m_repeat_length ? m_repeat_length : len; 00788 } 00789 else 00790 { 00791 OnDisconnect(); 00792 OnDisconnect(TCP_DISCONNECT_WRITE|TCP_DISCONNECT_ERROR|TCP_DISCONNECT_SSL, errnr); 00793 SetCloseAndDelete(true); 00794 SetFlushBeforeClose(false); 00795 SetLost(); 00796 { 00797 char errbuf[256]; 00798 ERR_error_string_n(errnr, errbuf, 256); 00799 Handler().LogError(this, "OnWrite/SSL_write", errnr, errbuf, LOG_LEVEL_FATAL); 00800 } 00801 } 00802 return 0; 00803 } 00804 else 00805 if (!n) 00806 { 00807 OnDisconnect(); 00808 OnDisconnect(TCP_DISCONNECT_WRITE|TCP_DISCONNECT_SSL, 0); 00809 SetCloseAndDelete(true); 00810 SetFlushBeforeClose(false); 00811 SetLost(); 00812 } 00813 m_repeat_length = 0; 00814 } 00815 else 00816 #endif // HAVE_OPENSSL 00817 { 00818 n = send(GetSocket(), buf, (int)len, MSG_NOSIGNAL); 00819 if (n == -1) 00820 { 00821 // normal error codes: 00822 // WSAEWOULDBLOCK 00823 // EAGAIN or EWOULDBLOCK 00824 #ifdef _WIN32 00825 if (Errno != WSAEWOULDBLOCK) 00826 #else 00827 if (Errno != EWOULDBLOCK) 00828 #endif 00829 { 00830 Handler().LogError(this, "send", Errno, StrError(Errno), LOG_LEVEL_FATAL); 00831 OnDisconnect(); 00832 OnDisconnect(TCP_DISCONNECT_WRITE|TCP_DISCONNECT_ERROR, Errno); 00833 SetCloseAndDelete(true); 00834 SetFlushBeforeClose(false); 00835 SetLost(); 00836 } 00837 return 0; 00838 } 00839 } 00840 if (n > 0) 00841 { 00842 m_bytes_sent += n; 00843 if (GetTrafficMonitor()) 00844 { 00845 GetTrafficMonitor() -> fwrite(buf, 1, n); 00846 } 00847 } 00848 return n; 00849 }
| void TcpSocket::Buffer | ( | const char * | buf, | |
| size_t | len | |||
| ) | [private] |
add data to output buffer top
Definition at line 852 of file TcpSocket.cpp.
References m_obuf, m_obuf_top, and m_output_length.
Referenced by SendBuf().
00853 { 00854 size_t ptr = 0; 00855 m_output_length += len; 00856 while (ptr < len) 00857 { 00858 // buf/len => pbuf/sz 00859 size_t space = 0; 00860 if (m_obuf_top && (space = m_obuf_top -> Space()) > 0) 00861 { 00862 const char *pbuf = buf + ptr; 00863 size_t sz = len - ptr; 00864 if (space >= sz) 00865 { 00866 m_obuf_top -> Add(pbuf, sz); 00867 ptr += sz; 00868 } 00869 else 00870 { 00871 m_obuf_top -> Add(pbuf, space); 00872 ptr += space; 00873 } 00874 } 00875 else 00876 { 00877 m_obuf_top = new OUTPUT; 00878 m_obuf.push_back( m_obuf_top ); 00879 } 00880 } 00881 }
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