![]() |
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. | |
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. | |
size_t | GetInputLength () |
Number of bytes in input buffer. | |
size_t | GetOutputLength () |
Number of bytes in output buffer. | |
void | OnLine (const std::string &line) |
Callback fires when a socket in line protocol has read one full line. | |
uint64_t | GetBytesReceived (bool clear=false) |
Get counter of number of bytes received. | |
uint64_t | GetBytesSent (bool clear=false) |
Get counter of number of bytes sent. | |
void | OnSocks4Connect () |
Socks4 specific callback. | |
void | OnSocks4ConnectFailed () |
Socks4 specific callback. | |
bool | OnSocks4Read () |
Socks4 specific callback. | |
void | OnResolved (int id, ipaddr_t a, port_t port) |
Callback executed when resolver thread has finished a resolve request. | |
void | OnSSLConnect () |
Callback for 'New' ssl support - replaces SSLSocket. | |
void | OnSSLAccept () |
Callback for 'New' ssl support - replaces SSLSocket. | |
virtual void | InitSSLClient () |
This method must be implemented to initialize the ssl context for an outgoing connection. | |
virtual void | InitSSLServer () |
This method must be implemented to initialize the ssl context for an incoming connection. | |
void | SetReconnect (bool=true) |
Flag that says a broken connection will try to reconnect. | |
bool | Reconnect () |
Check reconnect on lost connection flag status. | |
void | SetIsReconnect (bool x=true) |
Flag to determine if a reconnect is in progress. | |
bool | IsReconnect () |
Socket is reconnecting. | |
void | DisableInputBuffer (bool=true) |
void | OnOptions (int, int, int, SOCKET) |
Called when a socket is created, to set socket options. | |
void | SetLineProtocol (bool=true) |
Enable the OnLine callback. | |
Protected Member Functions | |
TcpSocket (const TcpSocket &s) | |
void | OnRead () |
Called when there is something to be read from the file descriptor. | |
void | OnWrite () |
Called when there is room for another write on the file descriptor. | |
void | InitializeContext (const std::string &context, SSL_METHOD *meth_in=NULL) |
SSL; Initialize ssl context for a client socket. | |
void | InitializeContext (const std::string &context, const std::string &keyfile, const std::string &password, SSL_METHOD *meth_in=NULL) |
SSL; Initialize ssl context for a server socket. | |
virtual SSL_CTX * | GetSslContext () |
SSL; Get pointer to ssl context structure. | |
virtual SSL * | GetSsl () |
SSL; Get pointer to ssl structure. | |
bool | SSLNegotiate () |
ssl; still negotiating connection. | |
const std::string & | GetPassword () |
SSL; Get ssl password. | |
Static Protected Member Functions | |
static int | SSL_password_cb (char *buf, int num, int rwflag, void *userdata) |
SSL; Password callback method. | |
Protected Attributes | |
CircularBuffer | ibuf |
Circular input buffer. | |
CircularBuffer | obuf |
Circular output buffer. | |
Private Types | |
typedef std::list< MES * > | ucharp_v |
Dynamic output buffer list. | |
Private Member Functions | |
TcpSocket & | operator= (const TcpSocket &) |
Private Attributes | |
bool | m_b_input_buffer_disabled |
uint64_t | m_bytes_sent |
uint64_t | m_bytes_received |
bool | m_skip_c |
Skip second char of CRLF or LFCR sequence in OnRead. | |
char | m_c |
First char in CRLF or LFCR sequence. | |
std::string | m_line |
Current line in line protocol mode. | |
ucharp_v | m_mes |
overflow protection, dynamic output buffer | |
char * | m_buf |
temporary read buffer | |
SSL_CTX * | m_ssl_ctx |
ssl context | |
SSL * | m_ssl |
ssl 'socket' | |
BIO * | m_sbio |
ssl bio | |
std::string | m_password |
ssl password | |
int | m_socks4_state |
socks4 support | |
char | m_socks4_vn |
socks4 support, temporary variable | |
char | m_socks4_cd |
socks4 support, temporary variable | |
unsigned short | m_socks4_dstport |
socks4 support | |
unsigned long | m_socks4_dstip |
socks4 support | |
int | m_resolver_id |
Resolver id (if any) for current Open call. | |
bool | m_b_reconnect |
Reconnect on lost connection flag. | |
bool | m_b_is_reconnect |
Trying to reconnect. | |
Static Private Attributes | |
static SSLInitializer | m_ssl_init |
Classes | |
struct | MES |
Dynamic output buffer storage struct. More... |
Definition at line 53 of file TcpSocket.h.
typedef std::list<MES *> TcpSocket::ucharp_v [private] |
TcpSocket::TcpSocket | ( | ISocketHandler & | ) |
Constructor with standard values on input/output buffers.
Definition at line 75 of file TcpSocket.cpp.
00075 : Socket(h) 00076 ,ibuf(*this, TCP_BUFSIZE_READ) 00077 ,obuf(*this, 32768) 00078 ,m_b_input_buffer_disabled(false) 00079 ,m_bytes_sent(0) 00080 ,m_bytes_received(0) 00081 ,m_skip_c(false) 00082 #ifdef SOCKETS_DYNAMIC_TEMP 00083 ,m_buf(new char[TCP_BUFSIZE_READ + 1]) 00084 #endif 00085 #ifdef HAVE_OPENSSL 00086 ,m_ssl_ctx(NULL) 00087 ,m_ssl(NULL) 00088 ,m_sbio(NULL) 00089 #endif 00090 #ifdef ENABLE_SOCKS4 00091 ,m_socks4_state(0) 00092 #endif 00093 #ifdef ENABLE_RESOLVER 00094 ,m_resolver_id(0) 00095 #endif 00096 #ifdef ENABLE_RECONNECT 00097 ,m_b_reconnect(false) 00098 ,m_b_is_reconnect(false) 00099 #endif 00100 { 00101 }
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 110 of file TcpSocket.cpp.
00110 : Socket(h) 00111 ,ibuf(*this, isize) 00112 ,obuf(*this, osize) 00113 ,m_b_input_buffer_disabled(false) 00114 ,m_bytes_sent(0) 00115 ,m_bytes_received(0) 00116 ,m_skip_c(false) 00117 #ifdef SOCKETS_DYNAMIC_TEMP 00118 ,m_buf(new char[TCP_BUFSIZE_READ + 1]) 00119 #endif 00120 #ifdef HAVE_OPENSSL 00121 ,m_ssl_ctx(NULL) 00122 ,m_ssl(NULL) 00123 ,m_sbio(NULL) 00124 #endif 00125 #ifdef ENABLE_SOCKS4 00126 ,m_socks4_state(0) 00127 #endif 00128 #ifdef ENABLE_RESOLVER 00129 ,m_resolver_id(0) 00130 #endif 00131 #ifdef ENABLE_RECONNECT 00132 ,m_b_reconnect(false) 00133 ,m_b_is_reconnect(false) 00134 #endif 00135 { 00136 }
TcpSocket::~TcpSocket | ( | ) |
Definition at line 142 of file TcpSocket.cpp.
References Socket::Handler(), LOG_LEVEL_WARNING, ISocketHandler::LogError(), m_buf, m_mes, and m_ssl.
00143 { 00144 if (m_mes.size()) 00145 { 00146 Handler().LogError(this, "TcpSocket destructor", 0, "Output buffer not empty", LOG_LEVEL_WARNING); 00147 } 00148 while (m_mes.size()) 00149 { 00150 ucharp_v::iterator it = m_mes.begin(); 00151 MES *p = *it; 00152 delete p; 00153 m_mes.erase(it); 00154 } 00155 #ifdef SOCKETS_DYNAMIC_TEMP 00156 delete[] m_buf; 00157 #endif 00158 #ifdef HAVE_OPENSSL 00159 if (m_ssl) 00160 { 00161 SSL_free(m_ssl); 00162 } 00163 #endif 00164 }
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 167 of file TcpSocket.cpp.
Referenced by HttpGetSocket::HttpGetSocket(), MinderSocket::OnLine(), OnResolved(), Open(), HttpPutSocket::Open(), and HttpPostSocket::Open().
00168 { 00169 Ipv4Address ad(ip, port); 00170 Ipv4Address local; 00171 return Open(ad, local, skip_socks); 00172 }
bool TcpSocket::Open | ( | SocketAddress & | , | |
bool | skip_socks = false | |||
) |
Definition at line 186 of file TcpSocket.cpp.
References Open().
00187 { 00188 Ipv4Address bind_ad("0.0.0.0", 0); 00189 return Open(ad, bind_ad, skip_socks); 00190 }
bool TcpSocket::Open | ( | SocketAddress & | , | |
SocketAddress & | bind_address, | |||
bool | skip_socks = false | |||
) |
Definition at line 193 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(), Socket::SetConnecting(), Socket::SetIsClient(), Socket::SetNonblocking(), Socket::SetRemoteAddress(), Socket::SetSocks4(), Socket::Socks4(), and StrError.
00194 { 00195 if (!ad.IsValid()) 00196 { 00197 Handler().LogError(this, "Open", 0, "Invalid SocketAddress", LOG_LEVEL_FATAL); 00198 SetCloseAndDelete(); 00199 return false; 00200 } 00201 if (Handler().GetCount() >= FD_SETSIZE) 00202 { 00203 Handler().LogError(this, "Open", 0, "no space left in fd_set", LOG_LEVEL_FATAL); 00204 SetCloseAndDelete(); 00205 return false; 00206 } 00207 SetConnecting(false); 00208 #ifdef ENABLE_SOCKS4 00209 SetSocks4(false); 00210 #endif 00211 // check for pooling 00212 #ifdef ENABLE_POOL 00213 if (Handler().PoolEnabled()) 00214 { 00215 ISocketHandler::PoolSocket *pools = Handler().FindConnection(SOCK_STREAM, "tcp", ad); 00216 if (pools) 00217 { 00218 CopyConnection( pools ); 00219 delete pools; 00220 00221 SetIsClient(); 00222 SetCallOnConnect(); // ISocketHandler must call OnConnect 00223 Handler().LogError(this, "SetCallOnConnect", 0, "Found pooled connection", LOG_LEVEL_INFO); 00224 return true; 00225 } 00226 } 00227 #endif 00228 // if not, create new connection 00229 SOCKET s = CreateSocket(ad.GetFamily(), SOCK_STREAM, "tcp"); 00230 if (s == INVALID_SOCKET) 00231 { 00232 return false; 00233 } 00234 // socket must be nonblocking for async connect 00235 if (!SetNonblocking(true, s)) 00236 { 00237 SetCloseAndDelete(); 00238 closesocket(s); 00239 return false; 00240 } 00241 #ifdef ENABLE_POOL 00242 SetIsClient(); // client because we connect 00243 #endif 00244 SetClientRemoteAddress(ad); 00245 int n = 0; 00246 if (bind_ad.GetPort() != 0) 00247 { 00248 bind(s, bind_ad, bind_ad); 00249 } 00250 #ifdef ENABLE_SOCKS4 00251 if (!skip_socks && GetSocks4Host() && GetSocks4Port()) 00252 { 00253 Ipv4Address sa(GetSocks4Host(), GetSocks4Port()); 00254 { 00255 std::string sockshost; 00256 Utility::l2ip(GetSocks4Host(), sockshost); 00257 Handler().LogError(this, "Open", 0, "Connecting to socks4 server @ " + sockshost + ":" + 00258 Utility::l2string(GetSocks4Port()), LOG_LEVEL_INFO); 00259 } 00260 SetSocks4(); 00261 n = connect(s, sa, sa); 00262 SetRemoteAddress(sa); 00263 } 00264 else 00265 #endif 00266 { 00267 n = connect(s, ad, ad); 00268 SetRemoteAddress(ad); 00269 } 00270 if (n == -1) 00271 { 00272 // check error code that means a connect is in progress 00273 #ifdef _WIN32 00274 if (Errno == WSAEWOULDBLOCK) 00275 #else 00276 if (Errno == EINPROGRESS) 00277 #endif 00278 { 00279 Attach(s); 00280 SetConnecting( true ); // this flag will control fd_set's 00281 } 00282 else 00283 #ifdef ENABLE_SOCKS4 00284 if (Socks4() && Handler().Socks4TryDirect() ) // retry 00285 { 00286 closesocket(s); 00287 return Open(ad, true); 00288 } 00289 else 00290 #endif 00291 #ifdef ENABLE_RECONNECT 00292 if (Reconnect()) 00293 { 00294 Handler().LogError(this, "connect: failed, reconnect pending", Errno, StrError(Errno), LOG_LEVEL_INFO); 00295 Attach(s); 00296 SetConnecting( true ); // this flag will control fd_set's 00297 } 00298 else 00299 #endif 00300 { 00301 Handler().LogError(this, "connect: failed", Errno, StrError(Errno), LOG_LEVEL_FATAL); 00302 SetCloseAndDelete(); 00303 closesocket(s); 00304 return false; 00305 } 00306 } 00307 else 00308 { 00309 Attach(s); 00310 SetCallOnConnect(); // ISocketHandler must call OnConnect 00311 } 00312 00313 // 'true' means connected or connecting(not yet connected) 00314 // 'false' means something failed 00315 return true; 00316 }
bool TcpSocket::Open | ( | const std::string & | host, | |
port_t | port | |||
) |
Open connection.
host | Hostname | |
port | Port number |
Definition at line 319 of file TcpSocket.cpp.
References Socket::Handler(), Utility::isipv4(), m_resolver_id, Open(), Socket::Resolve(), Socket::SetCloseAndDelete(), and Utility::u2ip().
00320 { 00321 #ifdef ENABLE_IPV6 00322 #ifdef IPPROTO_IPV6 00323 if (IsIpv6()) 00324 { 00325 #ifdef ENABLE_RESOLVER 00326 if (!Handler().ResolvedEnabled() || Utility::isipv4(host) ) 00327 { 00328 #endif 00329 in6_addr a; 00330 if (!Utility::u2ip(host, a)) 00331 { 00332 SetCloseAndDelete(); 00333 return false; 00334 } 00335 Ipv6Address ad(a, port); 00336 Ipv6Address local; 00337 return Open(ad, local); 00338 #ifdef ENABLE_RESOLVER 00339 } 00340 m_resolver_id = Resolve6(host, port); 00341 return true; 00342 #endif 00343 } 00344 #endif 00345 #endif 00346 #ifdef ENABLE_RESOLVER 00347 if (!Handler().ResolverEnabled() || Utility::isipv4(host) ) 00348 { 00349 #endif 00350 ipaddr_t l; 00351 if (!Utility::u2ip(host,l)) 00352 { 00353 SetCloseAndDelete(); 00354 return false; 00355 } 00356 Ipv4Address ad(l, port); 00357 Ipv4Address local; 00358 return Open(ad, local); 00359 #ifdef ENABLE_RESOLVER 00360 } 00361 // resolve using async resolver thread 00362 m_resolver_id = Resolve(host, port); 00363 return true; 00364 #endif 00365 }
int TcpSocket::Close | ( | ) | [virtual] |
Close file descriptor - internal use only.
Reimplemented from Socket.
Definition at line 1254 of file TcpSocket.cpp.
References Socket::Close(), Socket::IsSSL(), and m_ssl.
01255 { 01256 #ifdef HAVE_OPENSSL 01257 if (IsSSL() && m_ssl) 01258 SSL_shutdown(m_ssl); 01259 if (m_ssl) 01260 { 01261 SSL_free(m_ssl); 01262 m_ssl = NULL; 01263 } 01264 #endif 01265 return Socket::Close(); 01266 }
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 791 of file TcpSocket.cpp.
References SendBuf().
Referenced by HttpPostSocket::DoMultipartPost(), SmtpdSocket::OnAccept(), ResolvSocket::OnConnect(), HttpPostSocket::OnConnect(), HttpDebugSocket::OnData(), ResolvSocket::OnDetached(), HttpDebugSocket::OnFirst(), HttpDebugSocket::OnHeader(), HttpDebugSocket::OnHeaderComplete(), SmtpdSocket::OnLine(), MinionSocket::OnLine(), MinionSocket::OnVerifiedLine(), Sendf(), MinionSocket::SendHello(), MinderSocket::SendHello(), HTTPSocket::SendRequest(), and HTTPSocket::SendResponse().
00792 { 00793 SendBuf(str.c_str(),str.size(),i); 00794 }
void TcpSocket::Sendf | ( | const char * | format, | |
... | ||||
) |
Send string using printf formatting.
Definition at line 978 of file TcpSocket.cpp.
References Send().
00979 { 00980 va_list ap; 00981 va_start(ap, format); 00982 char slask[5000]; // vsprintf / vsnprintf temporary 00983 #ifdef _WIN32 00984 vsprintf(slask, format, ap); 00985 #else 00986 vsnprintf(slask, 5000, format, ap); 00987 #endif 00988 va_end(ap); 00989 Send( slask ); 00990 }
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 797 of file TcpSocket.cpp.
References Socket::CloseAndDelete(), Socket::Connecting(), CircularBuffer::GetLength(), Socket::GetSocket(), Socket::Handler(), INVALID_SOCKET, Socket::IsConnected(), LOG_LEVEL_INFO, ISocketHandler::LogError(), m_mes, MAX_BLOCKSIZE, obuf, OnWrite(), Socket::Ready(), CircularBuffer::Space(), and CircularBuffer::Write().
Referenced by HttpPostSocket::DoMultipartPost(), HttpPutSocket::OnConnect(), HttpDebugSocket::OnData(), OnSocks4Connect(), Send(), and HttpdSocket::Send64().
00798 { 00799 size_t n = obuf.GetLength(); 00800 if (!Ready() && !Connecting()) 00801 { 00802 Handler().LogError(this, "SendBuf", -1, "Attempt to write to a non-ready socket" ); // warning 00803 if (GetSocket() == INVALID_SOCKET) 00804 Handler().LogError(this, "SendBuf", 0, " * GetSocket() == INVALID_SOCKET", LOG_LEVEL_INFO); 00805 if (Connecting()) 00806 Handler().LogError(this, "SendBuf", 0, " * Connecting()", LOG_LEVEL_INFO); 00807 if (CloseAndDelete()) 00808 Handler().LogError(this, "SendBuf", 0, " * CloseAndDelete()", LOG_LEVEL_INFO); 00809 return; 00810 } 00811 if (!IsConnected()) 00812 { 00813 Handler().LogError(this, "SendBuf", -1, "Attempt to write to a non-connected socket, will be sent on connect" ); // warning 00814 } 00815 // 00816 size_t ptr = 0; 00817 if (!m_mes.size() && obuf.Space()) 00818 { 00819 if (len <= obuf.Space()) // entire block of data fits 00820 { 00821 ptr = len; 00822 obuf.Write(buf, len); 00823 } 00824 else // a part of the block fits 00825 { 00826 ptr = obuf.Space(); 00827 obuf.Write(buf, ptr); 00828 } 00829 } 00831 #define MAX_BLOCKSIZE 1024000 00832 while (ptr < len) // data still left to buffer 00833 { 00834 size_t sz = len - ptr; // size of data block that has not been buffered 00835 if (sz > MAX_BLOCKSIZE) 00836 sz = MAX_BLOCKSIZE; 00837 m_mes.push_back(new MES(buf + ptr, sz)); 00838 ptr += sz; 00839 } 00840 // kick a real write 00841 if (!n && IsConnected()) 00842 { 00843 OnWrite(); 00844 } 00845 }
void TcpSocket::OnRawData | ( | const char * | buf, | |
size_t | len | |||
) | [virtual] |
This callback is executed after a successful read from the socket.
buf | Pointer to the data | |
len | Length of the data |
Reimplemented in HTTPSocket.
Definition at line 1294 of file TcpSocket.cpp.
Referenced by OnRead().
size_t TcpSocket::GetInputLength | ( | ) |
Number of bytes in input buffer.
Definition at line 1299 of file TcpSocket.cpp.
References CircularBuffer::GetLength(), and ibuf.
Referenced by OnRead(), and OnSocks4Read().
size_t TcpSocket::GetOutputLength | ( | ) |
Number of bytes in output buffer.
Definition at line 1305 of file TcpSocket.cpp.
References CircularBuffer::GetLength(), and obuf.
Referenced by SSLNegotiate().
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, MinderSocket, MinionSocket, ResolvSocket, and SmtpdSocket.
Definition at line 848 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 1311 of file TcpSocket.cpp.
References m_bytes_received.
01312 { 01313 uint64_t z = m_bytes_received; 01314 if (clear) 01315 m_bytes_received = 0; 01316 return z; 01317 }
uint64_t TcpSocket::GetBytesSent | ( | bool | clear = false |
) | [virtual] |
Get counter of number of bytes sent.
Reimplemented from Socket.
Definition at line 1320 of file TcpSocket.cpp.
References m_bytes_sent.
01321 { 01322 uint64_t z = m_bytes_sent; 01323 if (clear) 01324 m_bytes_sent = 0; 01325 return z; 01326 }
void TcpSocket::OnSocks4Connect | ( | ) | [virtual] |
Socks4 specific callback.
Reimplemented from Socket.
Definition at line 868 of file TcpSocket.cpp.
References Socket::GetClientRemoteAddress(), Socket::GetSocks4Userid(), m_socks4_state, and SendBuf().
00869 { 00870 char request[1000]; 00871 memset(request, 0, sizeof(request)); 00872 request[0] = 4; // socks v4 00873 request[1] = 1; // command code: CONNECT 00874 { 00875 std::auto_ptr<SocketAddress> ad = GetClientRemoteAddress(); 00876 if (ad.get()) 00877 { 00878 struct sockaddr *p0 = (struct sockaddr *)*ad; 00879 struct sockaddr_in *p = (struct sockaddr_in *)p0; 00880 if (p -> sin_family == AF_INET) 00881 { 00882 memcpy(request + 2, &p -> sin_port, 2); // nwbo is ok here 00883 memcpy(request + 4, &p -> sin_addr, sizeof(struct in_addr)); 00884 } 00885 else 00886 { 00888 } 00889 } 00890 else 00891 { 00893 } 00894 } 00895 strcpy(request + 8, GetSocks4Userid().c_str()); 00896 size_t length = GetSocks4Userid().size() + 8 + 1; 00897 SendBuf(request, length); 00898 m_socks4_state = 0; 00899 }
void TcpSocket::OnSocks4ConnectFailed | ( | ) | [virtual] |
Socks4 specific callback.
Reimplemented from Socket.
Definition at line 902 of file TcpSocket.cpp.
References Socket::Handler(), LOG_LEVEL_WARNING, ISocketHandler::LogError(), Socket::OnConnectFailed(), Socket::SetCloseAndDelete(), Socket::SetConnecting(), and Socket::SetRetryClientConnect().
Referenced by OnWrite().
00903 { 00904 Handler().LogError(this,"OnSocks4ConnectFailed",0,"connection to socks4 server failed, trying direct connection",LOG_LEVEL_WARNING); 00905 if (!Handler().Socks4TryDirect()) 00906 { 00907 SetConnecting(false); 00908 SetCloseAndDelete(); 00909 OnConnectFailed(); // just in case 00910 } 00911 else 00912 { 00913 SetRetryClientConnect(); 00914 } 00915 }
bool TcpSocket::OnSocks4Read | ( | ) | [virtual] |
Socks4 specific callback.
Reimplemented from Socket.
Definition at line 918 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(), CircularBuffer::Read(), Socket::SetCloseAndDelete(), Socket::SetConnecting(), and Socket::SetSocks4().
Referenced by OnRead().
00919 { 00920 switch (m_socks4_state) 00921 { 00922 case 0: 00923 ibuf.Read(&m_socks4_vn, 1); 00924 m_socks4_state = 1; 00925 break; 00926 case 1: 00927 ibuf.Read(&m_socks4_cd, 1); 00928 m_socks4_state = 2; 00929 break; 00930 case 2: 00931 if (GetInputLength() > 1) 00932 { 00933 ibuf.Read( (char *)&m_socks4_dstport, 2); 00934 m_socks4_state = 3; 00935 } 00936 else 00937 { 00938 return true; 00939 } 00940 break; 00941 case 3: 00942 if (GetInputLength() > 3) 00943 { 00944 ibuf.Read( (char *)&m_socks4_dstip, 4); 00945 SetSocks4(false); 00946 00947 switch (m_socks4_cd) 00948 { 00949 case 90: 00950 OnConnect(); 00951 Handler().LogError(this, "OnSocks4Read", 0, "Connection established", LOG_LEVEL_INFO); 00952 break; 00953 case 91: 00954 case 92: 00955 case 93: 00956 Handler().LogError(this,"OnSocks4Read",m_socks4_cd,"socks4 server reports connect failed",LOG_LEVEL_FATAL); 00957 SetConnecting(false); 00958 SetCloseAndDelete(); 00959 OnConnectFailed(); 00960 break; 00961 default: 00962 Handler().LogError(this,"OnSocks4Read",m_socks4_cd,"socks4 server unrecognized response",LOG_LEVEL_FATAL); 00963 SetCloseAndDelete(); 00964 break; 00965 } 00966 } 00967 else 00968 { 00969 return true; 00970 } 00971 break; 00972 } 00973 return false; 00974 }
Callback executed when resolver thread has finished a resolve request.
Reimplemented from Socket.
Definition at line 369 of file TcpSocket.cpp.
References ISocketHandler::Add(), Socket::Handler(), LOG_LEVEL_FATAL, ISocketHandler::LogError(), m_resolver_id, Open(), and Socket::SetCloseAndDelete().
Referenced by ResolvSocket::OnLine().
00370 { 00371 if (id == m_resolver_id) 00372 { 00373 if (a && port) 00374 { 00375 Ipv4Address ad(a, port); 00376 Ipv4Address local; 00377 if (Open(ad, local)) 00378 { 00379 if (!Handler().Valid(this)) 00380 { 00381 Handler().Add(this); 00382 } 00383 } 00384 } 00385 else 00386 { 00387 Handler().LogError(this, "OnResolved", 0, "Resolver failed", LOG_LEVEL_FATAL); 00388 SetCloseAndDelete(); 00389 } 00390 } 00391 else 00392 { 00393 Handler().LogError(this, "OnResolved", id, "Resolver returned wrong job id", LOG_LEVEL_FATAL); 00394 SetCloseAndDelete(); 00395 } 00396 }
void TcpSocket::OnSSLConnect | ( | ) | [virtual] |
Callback for 'New' ssl support - replaces SSLSocket.
Internal use.
Reimplemented from Socket.
Definition at line 994 of file TcpSocket.cpp.
References DEB, Socket::GetSocket(), InitSSLClient(), m_sbio, m_ssl, m_ssl_ctx, Socket::SetCloseAndDelete(), Socket::SetNonblocking(), and Socket::SetSSLNegotiate().
00995 { 00996 SetNonblocking(true); 00997 { 00998 if (m_ssl_ctx) 00999 { 01000 DEB( fprintf(stderr, "SSL Context already initialized - closing socket\n");) 01001 SetCloseAndDelete(true); 01002 return; 01003 } 01004 InitSSLClient(); 01005 } 01006 if (m_ssl_ctx) 01007 { 01008 /* Connect the SSL socket */ 01009 m_ssl = SSL_new(m_ssl_ctx); 01010 if (!m_ssl) 01011 { 01012 DEB( fprintf(stderr, " m_ssl is NULL\n");) 01013 SetCloseAndDelete(true); 01014 return; 01015 } 01016 SSL_set_mode(m_ssl, SSL_MODE_AUTO_RETRY); 01017 m_sbio = BIO_new_socket((int)GetSocket(), BIO_NOCLOSE); 01018 if (!m_sbio) 01019 { 01020 DEB( fprintf(stderr, " m_sbio is NULL\n");) 01021 SetCloseAndDelete(true); 01022 return; 01023 } 01024 SSL_set_bio(m_ssl, m_sbio, m_sbio); 01025 // if (!SSLNegotiate()) 01026 { 01027 SetSSLNegotiate(); 01028 } 01029 } 01030 else 01031 { 01032 SetCloseAndDelete(); 01033 } 01034 }
void TcpSocket::OnSSLAccept | ( | ) | [virtual] |
Callback for 'New' ssl support - replaces SSLSocket.
Internal use.
Reimplemented from Socket.
Definition at line 1037 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().
01038 { 01039 SetNonblocking(true); 01040 { 01041 if (m_ssl_ctx) 01042 { 01043 DEB( fprintf(stderr, "SSL Context already initialized - closing socket\n");) 01044 SetCloseAndDelete(true); 01045 return; 01046 } 01047 InitSSLServer(); 01048 SetSSLServer(); 01049 } 01050 if (m_ssl_ctx) 01051 { 01052 m_ssl = SSL_new(m_ssl_ctx); 01053 if (!m_ssl) 01054 { 01055 DEB( fprintf(stderr, " m_ssl is NULL\n");) 01056 SetCloseAndDelete(true); 01057 return; 01058 } 01059 SSL_set_mode(m_ssl, SSL_MODE_AUTO_RETRY); 01060 m_sbio = BIO_new_socket((int)GetSocket(), BIO_NOCLOSE); 01061 if (!m_sbio) 01062 { 01063 DEB( fprintf(stderr, " m_sbio is NULL\n");) 01064 SetCloseAndDelete(true); 01065 return; 01066 } 01067 SSL_set_bio(m_ssl, m_sbio, m_sbio); 01068 // if (!SSLNegotiate()) 01069 { 01070 SetSSLNegotiate(); 01071 } 01072 } 01073 }
void TcpSocket::InitSSLClient | ( | ) | [virtual] |
This method must be implemented to initialize the ssl context for an outgoing connection.
Definition at line 1173 of file TcpSocket.cpp.
References InitializeContext().
Referenced by OnSSLConnect().
01174 { 01175 InitializeContext("", SSLv23_method()); 01176 }
void TcpSocket::InitSSLServer | ( | ) | [virtual] |
This method must be implemented to initialize the ssl context for an incoming connection.
Definition at line 1179 of file TcpSocket.cpp.
References Socket::Handler(), LOG_LEVEL_FATAL, ISocketHandler::LogError(), and Socket::SetCloseAndDelete().
Referenced by OnSSLAccept().
01180 { 01181 Handler().LogError(this, "InitSSLServer", 0, "You MUST implement your own InitSSLServer method", LOG_LEVEL_FATAL); 01182 SetCloseAndDelete(); 01183 }
void TcpSocket::SetReconnect | ( | bool | = true |
) |
Flag that says a broken connection will try to reconnect.
Definition at line 1287 of file TcpSocket.cpp.
References m_b_reconnect.
01288 { 01289 m_b_reconnect = x; 01290 }
bool TcpSocket::Reconnect | ( | ) |
Check reconnect on lost connection flag status.
Definition at line 1330 of file TcpSocket.cpp.
References m_b_reconnect.
Referenced by Open().
01331 { 01332 return m_b_reconnect; 01333 }
void TcpSocket::SetIsReconnect | ( | bool | x = true |
) |
Flag to determine if a reconnect is in progress.
Definition at line 1336 of file TcpSocket.cpp.
References m_b_is_reconnect.
01337 { 01338 m_b_is_reconnect = x; 01339 }
bool TcpSocket::IsReconnect | ( | ) |
Socket is reconnecting.
Definition at line 1342 of file TcpSocket.cpp.
References m_b_is_reconnect.
Referenced by SSLNegotiate().
01343 { 01344 return m_b_is_reconnect; 01345 }
void TcpSocket::DisableInputBuffer | ( | bool | = true |
) |
Definition at line 1357 of file TcpSocket.cpp.
References m_b_input_buffer_disabled.
Referenced by HTTPSocket::HTTPSocket(), and SetLineProtocol().
01358 { 01359 m_b_input_buffer_disabled = x; 01360 }
void TcpSocket::OnOptions | ( | int | family, | |
int | type, | |||
int | protocol, | |||
SOCKET | ||||
) | [virtual] |
Called when a socket is created, to set socket options.
Implements Socket.
Definition at line 1363 of file TcpSocket.cpp.
References DEB, Socket::SetKeepalive(), and Socket::SetReuse().
01364 { 01365 DEB( fprintf(stderr, "Socket::OnOptions()\n");) 01366 /* 01367 Handler().LogError(this, "OnOptions", family, "Address Family", LOG_LEVEL_INFO); 01368 Handler().LogError(this, "OnOptions", type, "Type", LOG_LEVEL_INFO); 01369 Handler().LogError(this, "OnOptions", protocol, "Protocol", LOG_LEVEL_INFO); 01370 */ 01371 SetReuse(true); 01372 SetKeepalive(true); 01373 }
void TcpSocket::SetLineProtocol | ( | bool | = true |
) | [virtual] |
Enable the OnLine callback.
Do not create your own OnRead callback when using this.
Reimplemented from Socket.
Definition at line 1376 of file TcpSocket.cpp.
References DisableInputBuffer(), and Socket::SetLineProtocol().
Referenced by HTTPSocket::HTTPSocket(), MinderSocket::MinderSocket(), MinionSocket::MinionSocket(), HTTPSocket::OnLine(), HTTPSocket::Reset(), ResolvSocket::ResolvSocket(), and SmtpdSocket::SmtpdSocket().
01377 { 01378 Socket::SetLineProtocol(x); 01379 DisableInputBuffer(x); 01380 }
void TcpSocket::OnRead | ( | ) | [protected, virtual] |
Called when there is something to be read from the file descriptor.
Reimplemented from Socket.
Definition at line 427 of file TcpSocket.cpp.
References Socket::CloseAndDelete(), DEB, Errno, GetInputLength(), Socket::GetSocket(), Socket::GetTrafficMonitor(), Socket::Handler(), ibuf, Socket::IsSSL(), Socket::LineProtocol(), LOG_LEVEL_ERROR, LOG_LEVEL_FATAL, LOG_LEVEL_WARNING, ISocketHandler::LogError(), m_b_input_buffer_disabled, m_buf, m_bytes_received, m_c, m_line, m_skip_c, m_ssl, OnLine(), OnRawData(), OnSocks4Read(), Socket::Ready(), Socket::SetCloseAndDelete(), Socket::SetFlushBeforeClose(), Socket::SetLost(), Socket::SetShutdown(), Socket::Socks4(), StrError, TCP_BUFSIZE_READ, and CircularBuffer::Write().
00428 { 00429 int n = 0; 00430 #ifdef SOCKETS_DYNAMIC_TEMP 00431 char *buf = m_buf; 00432 #else 00433 char buf[TCP_BUFSIZE_READ]; 00434 #endif 00435 #ifdef HAVE_OPENSSL 00436 if (IsSSL()) 00437 { 00438 if (!Ready()) 00439 return; 00440 n = SSL_read(m_ssl, buf, TCP_BUFSIZE_READ); 00441 if (n == -1) 00442 { 00443 n = SSL_get_error(m_ssl, n); 00444 switch (n) 00445 { 00446 case SSL_ERROR_NONE: 00447 case SSL_ERROR_WANT_READ: 00448 case SSL_ERROR_WANT_WRITE: 00449 break; 00450 case SSL_ERROR_ZERO_RETURN: 00451 DEB( fprintf(stderr, "SSL_read() returns zero - closing socket\n");) 00452 SetCloseAndDelete(true); 00453 SetFlushBeforeClose(false); 00454 #ifdef ENABLE_POOL 00455 SetLost(); 00456 #endif 00457 break; 00458 default: 00459 DEB( fprintf(stderr, "SSL read problem, errcode = %d\n",n);) 00460 SetCloseAndDelete(true); 00461 SetFlushBeforeClose(false); 00462 #ifdef ENABLE_POOL 00463 SetLost(); 00464 #endif 00465 } 00466 return; 00467 } 00468 else 00469 if (!n) 00470 { 00471 Handler().LogError(this, "SSL_read", 0, "read returns 0", LOG_LEVEL_FATAL); 00472 SetCloseAndDelete(true); 00473 SetFlushBeforeClose(false); 00474 #ifdef ENABLE_POOL 00475 SetLost(); 00476 #endif 00477 SetShutdown(SHUT_WR); 00478 return; 00479 } 00480 else 00481 if (n > 0 && n <= TCP_BUFSIZE_READ) 00482 { 00483 m_bytes_received += n; 00484 if (GetTrafficMonitor()) 00485 { 00486 GetTrafficMonitor() -> fwrite(buf, 1, n); 00487 } 00488 if (!m_b_input_buffer_disabled && !ibuf.Write(buf,n)) 00489 { 00490 Handler().LogError(this, "OnRead(ssl)", 0, "ibuf overflow", LOG_LEVEL_WARNING); 00491 } 00492 } 00493 else 00494 { 00495 Handler().LogError(this, "OnRead(ssl)", n, "abnormal value from SSL_read", LOG_LEVEL_ERROR); 00496 } 00497 } 00498 else 00499 #endif // HAVE_OPENSSL 00500 { 00501 n = recv(GetSocket(), buf, TCP_BUFSIZE_READ, MSG_NOSIGNAL); 00502 if (n == -1) 00503 { 00504 Handler().LogError(this, "read", Errno, StrError(Errno), LOG_LEVEL_FATAL); 00505 SetCloseAndDelete(true); 00506 SetFlushBeforeClose(false); 00507 #ifdef ENABLE_POOL 00508 SetLost(); 00509 #endif 00510 return; 00511 } 00512 else 00513 if (!n) 00514 { 00515 SetCloseAndDelete(true); 00516 SetFlushBeforeClose(false); 00517 #ifdef ENABLE_POOL 00518 SetLost(); 00519 #endif 00520 SetShutdown(SHUT_WR); 00521 return; 00522 } 00523 else 00524 if (n > 0 && n <= TCP_BUFSIZE_READ) 00525 { 00526 m_bytes_received += n; 00527 if (GetTrafficMonitor()) 00528 { 00529 GetTrafficMonitor() -> fwrite(buf, 1, n); 00530 } 00531 if (!m_b_input_buffer_disabled && !ibuf.Write(buf,n)) 00532 { 00533 Handler().LogError(this, "OnRead", 0, "ibuf overflow", LOG_LEVEL_WARNING); 00534 } 00535 } 00536 else 00537 { 00538 Handler().LogError(this, "OnRead", n, "abnormal value from recv", LOG_LEVEL_ERROR); 00539 } 00540 } 00541 // unbuffered 00542 if (n > 0 && n <= TCP_BUFSIZE_READ) 00543 { 00544 if (LineProtocol()) 00545 { 00546 size_t x = 0; 00547 00548 buf[n] = 0; 00549 int i = 0; 00550 if (m_skip_c && (buf[i] == 13 || buf[i] == 10) && buf[i] != m_c) 00551 { 00552 m_skip_c = false; 00553 i++; 00554 } 00555 for (; i < n && LineProtocol(); i++) 00556 { 00557 while ((buf[i] == 13 || buf[i] == 10) && LineProtocol()) 00558 { 00559 char c = buf[i]; 00560 buf[i] = 0; 00561 if (buf[x]) 00562 { 00563 m_line += (buf + x); 00564 } 00565 OnLine( m_line ); 00566 i++; 00567 m_skip_c = true; 00568 m_c = c; 00569 if (i < n && (buf[i] == 13 || buf[i] == 10) && buf[i] != c) 00570 { 00571 m_skip_c = false; 00572 i++; 00573 } 00574 x = i; 00575 m_line = ""; 00576 } 00577 if (!LineProtocol()) 00578 { 00579 break; 00580 } 00581 } 00582 if (!LineProtocol()) 00583 { 00584 if (i < n) 00585 { 00586 OnRawData(buf + i, n - i); 00587 } 00588 } 00589 else 00590 if (buf[x]) 00591 { 00592 m_line += (buf + x); 00593 } 00594 } 00595 else 00596 { 00597 OnRawData(buf, n); 00598 } 00599 } 00600 if (m_b_input_buffer_disabled) 00601 { 00602 return; 00603 } 00604 // further processing: socks4 00605 #ifdef ENABLE_SOCKS4 00606 if (Socks4()) 00607 { 00608 bool need_more = false; 00609 while (GetInputLength() && !need_more && !CloseAndDelete()) 00610 { 00611 need_more = OnSocks4Read(); 00612 } 00613 } 00614 #endif 00615 }
void TcpSocket::OnWrite | ( | ) | [protected, virtual] |
Called when there is room for another write on the file descriptor.
Reimplemented from Socket.
Definition at line 618 of file TcpSocket.cpp.
References Socket::CheckConnect(), Socket::Connecting(), DEB, Errno, ISocketHandler::Get(), Socket::GetConnectionRetries(), Socket::GetConnectionRetry(), CircularBuffer::GetLength(), Socket::GetSocket(), CircularBuffer::GetStart(), Socket::GetTrafficMonitor(), Socket::Handler(), Socket::IsSSL(), LOG_LEVEL_FATAL, ISocketHandler::LogError(), m_bytes_sent, m_mes, m_ssl, obuf, Socket::OnConnectFailed(), OnSocks4ConnectFailed(), CircularBuffer::Remove(), Socket::Set(), Socket::SetCallOnConnect(), Socket::SetCloseAndDelete(), Socket::SetConnecting(), Socket::SetFlushBeforeClose(), Socket::SetLost(), Socket::Socks4(), CircularBuffer::Space(), StrError, and CircularBuffer::Write().
Referenced by SendBuf(), and SSLNegotiate().
00619 { 00620 if (Connecting()) 00621 { 00622 if (CheckConnect()) 00623 { 00624 SetCallOnConnect(); 00625 return; 00626 } 00627 // failed 00628 #ifdef ENABLE_SOCKS4 00629 if (Socks4()) 00630 { 00631 OnSocks4ConnectFailed(); 00632 return; 00633 } 00634 #endif 00635 if (GetConnectionRetry() == -1 || 00636 (GetConnectionRetry() && GetConnectionRetries() < GetConnectionRetry()) ) 00637 { 00638 // even though the connection failed at once, only retry after 00639 // the connection timeout. 00640 // should we even try to connect again, when CheckConnect returns 00641 // false it's because of a connection error - not a timeout... 00642 return; 00643 } 00644 SetConnecting(false); 00645 SetCloseAndDelete( true ); 00647 OnConnectFailed(); 00648 return; 00649 } 00650 #ifdef HAVE_OPENSSL 00651 if (IsSSL()) 00652 { 00653 int n = SSL_write(m_ssl,obuf.GetStart(),(int)obuf.GetLength()); 00654 int errnr = n < 1 ? SSL_get_error(m_ssl, n) : 0; 00655 if (n == -1) 00656 { 00657 if ( errnr != SSL_ERROR_WANT_READ && errnr != SSL_ERROR_WANT_WRITE ) 00658 { 00659 SetCloseAndDelete(true); 00660 SetFlushBeforeClose(false); 00661 #ifdef ENABLE_POOL 00662 SetLost(); 00663 #endif 00664 const char *errbuf = ERR_error_string(errnr, NULL); 00665 Handler().LogError(this, "OnWrite/SSL_write", errnr, errbuf, LOG_LEVEL_FATAL); 00666 } 00667 } 00668 else 00669 if (!n) 00670 { 00671 SetCloseAndDelete(true); 00672 SetFlushBeforeClose(false); 00673 #ifdef ENABLE_POOL 00674 SetLost(); 00675 #endif 00676 DEB( const char *errbuf = ERR_error_string(errnr, NULL); 00677 fprintf(stderr, "SSL_write() returns 0: %d : %s\n",errnr, errbuf);) 00678 } 00679 else 00680 { 00681 m_bytes_sent += n; 00682 if (GetTrafficMonitor()) 00683 { 00684 GetTrafficMonitor() -> fwrite(obuf.GetStart(), 1, n); 00685 } 00686 obuf.Remove(n); 00687 // move data from m_mes to immediate output buffer 00688 while (obuf.Space() && m_mes.size()) 00689 { 00690 ucharp_v::iterator it = m_mes.begin(); 00691 MES *p = *it; 00692 if (obuf.Space() > p -> left()) 00693 { 00694 obuf.Write(p -> curbuf(),p -> left()); 00695 delete p; 00696 m_mes.erase(it); 00697 } 00698 else 00699 { 00700 size_t sz = obuf.Space(); 00701 obuf.Write(p -> curbuf(),sz); 00702 p -> ptr += sz; 00703 } 00704 } 00705 } 00706 // 00707 { 00708 bool br; 00709 bool bw; 00710 bool bx; 00711 Handler().Get(GetSocket(), br, bw, bx); 00712 if (obuf.GetLength() || m_mes.size()) 00713 Set(br, true); 00714 else 00715 Set(br, false); 00716 } 00717 return; 00718 } 00719 #endif // HAVE_OPENSSL 00720 int n = send(GetSocket(),obuf.GetStart(),(int)obuf.GetLength(),MSG_NOSIGNAL); 00721 /* 00722 When writing onto a connection-oriented socket that has been shut down (by the local 00723 or the remote end) SIGPIPE is sent to the writing process and EPIPE is returned. The 00724 signal is not sent when the write call specified the MSG_NOSIGNAL flag. 00725 */ 00726 if (n == -1) 00727 { 00728 // normal error codes: 00729 // WSAEWOULDBLOCK 00730 // EAGAIN or EWOULDBLOCK 00731 #ifdef _WIN32 00732 if (Errno != WSAEWOULDBLOCK) 00733 #else 00734 if (Errno != EWOULDBLOCK) 00735 #endif 00736 { 00737 Handler().LogError(this, "send", Errno, StrError(Errno), LOG_LEVEL_FATAL); 00738 SetCloseAndDelete(true); 00739 SetFlushBeforeClose(false); 00740 #ifdef ENABLE_POOL 00741 SetLost(); 00742 #endif 00743 } 00744 } 00745 else 00746 if (!n) 00747 { 00748 // SetCloseAndDelete(true); 00749 } 00750 else 00751 { 00752 m_bytes_sent += n; 00753 if (GetTrafficMonitor()) 00754 { 00755 GetTrafficMonitor() -> fwrite(obuf.GetStart(), 1, n); 00756 } 00757 obuf.Remove(n); 00758 // move data from m_mes to immediate output buffer 00759 while (obuf.Space() && m_mes.size()) 00760 { 00761 ucharp_v::iterator it = m_mes.begin(); 00762 MES *p = *it; 00763 if (obuf.Space() > p -> left()) 00764 { 00765 obuf.Write(p -> curbuf(),p -> left()); 00766 delete p; 00767 m_mes.erase(it); 00768 } 00769 else 00770 { 00771 size_t sz = obuf.Space(); 00772 obuf.Write(p -> curbuf(),sz); 00773 p -> ptr += sz; 00774 } 00775 } 00776 } 00777 // set write flag if data still left to write 00778 { 00779 bool br; 00780 bool bw; 00781 bool bx; 00782 Handler().Get(GetSocket(), br, bw, bx); 00783 if (obuf.GetLength() || m_mes.size()) 00784 Set(br, true); 00785 else 00786 Set(br, false); 00787 } 00788 }
void TcpSocket::InitializeContext | ( | const std::string & | context, | |
SSL_METHOD * | meth_in = NULL | |||
) | [protected] |
SSL; Initialize ssl context for a client socket.
meth_in | SSL method |
Definition at line 1186 of file TcpSocket.cpp.
References m_ssl_ctx.
Referenced by InitSSLClient().
01187 { 01188 /* Create our context*/ 01189 static std::map<std::string, SSL_CTX *> client_contexts; 01190 if (client_contexts.find(context) == client_contexts.end()) 01191 { 01192 SSL_METHOD *meth = meth_in ? meth_in : SSLv3_method(); 01193 m_ssl_ctx = client_contexts[context] = SSL_CTX_new(meth); 01194 SSL_CTX_set_mode(m_ssl_ctx, SSL_MODE_AUTO_RETRY); 01195 } 01196 else 01197 { 01198 m_ssl_ctx = client_contexts[context]; 01199 } 01200 }
void TcpSocket::InitializeContext | ( | const std::string & | context, | |
const std::string & | keyfile, | |||
const std::string & | password, | |||
SSL_METHOD * | meth_in = NULL | |||
) | [protected] |
SSL; Initialize ssl context for a server socket.
keyfile | Combined private key/certificate file | |
password | Password for private key | |
meth_in | SSL method |
Definition at line 1203 of file TcpSocket.cpp.
References Socket::Handler(), LOG_LEVEL_FATAL, ISocketHandler::LogError(), m_password, m_ssl_ctx, and SSL_password_cb().
01204 { 01205 /* Create our context*/ 01206 static std::map<std::string, SSL_CTX *> server_contexts; 01207 if (server_contexts.find(context) == server_contexts.end()) 01208 { 01209 SSL_METHOD *meth = meth_in ? meth_in : SSLv3_method(); 01210 m_ssl_ctx = server_contexts[context] = SSL_CTX_new(meth); 01211 SSL_CTX_set_mode(m_ssl_ctx, SSL_MODE_AUTO_RETRY); 01212 // session id 01213 if (context.size()) 01214 SSL_CTX_set_session_id_context(m_ssl_ctx, (const unsigned char *)context.c_str(), (unsigned int)context.size()); 01215 else 01216 SSL_CTX_set_session_id_context(m_ssl_ctx, (const unsigned char *)"--empty--", 9); 01217 } 01218 else 01219 { 01220 m_ssl_ctx = server_contexts[context]; 01221 } 01222 01223 /* Load our keys and certificates*/ 01224 if (!(SSL_CTX_use_certificate_file(m_ssl_ctx, keyfile.c_str(), SSL_FILETYPE_PEM))) 01225 { 01226 Handler().LogError(this, "TcpSocket InitializeContext", 0, "Couldn't read certificate file " + keyfile, LOG_LEVEL_FATAL); 01227 } 01228 01229 m_password = password; 01230 SSL_CTX_set_default_passwd_cb(m_ssl_ctx, SSL_password_cb); 01231 SSL_CTX_set_default_passwd_cb_userdata(m_ssl_ctx, this); 01232 if (!(SSL_CTX_use_PrivateKey_file(m_ssl_ctx, keyfile.c_str(), SSL_FILETYPE_PEM))) 01233 { 01234 Handler().LogError(this, "TcpSocket InitializeContext", 0, "Couldn't read private key file " + keyfile, LOG_LEVEL_FATAL); 01235 } 01236 }
int TcpSocket::SSL_password_cb | ( | char * | buf, | |
int | num, | |||
int | rwflag, | |||
void * | userdata | |||
) | [static, protected] |
SSL; Password callback method.
Definition at line 1239 of file TcpSocket.cpp.
References GetPassword().
Referenced by InitializeContext().
01240 { 01241 Socket *p0 = static_cast<Socket *>(userdata); 01242 TcpSocket *p = dynamic_cast<TcpSocket *>(p0); 01243 std::string pw = p ? p -> GetPassword() : ""; 01244 if ( (size_t)num < pw.size() + 1) 01245 { 01246 return 0; 01247 } 01248 strcpy(buf,pw.c_str()); 01249 return (int)pw.size(); 01250 }
SSL_CTX * TcpSocket::GetSslContext | ( | ) | [protected, virtual] |
SSL; Get pointer to ssl context structure.
Reimplemented from Socket.
Definition at line 1270 of file TcpSocket.cpp.
References Socket::Handler(), LOG_LEVEL_WARNING, ISocketHandler::LogError(), and m_ssl_ctx.
01271 { 01272 if (!m_ssl_ctx) 01273 Handler().LogError(this, "GetSslContext", 0, "SSL Context is NULL; check InitSSLServer/InitSSLClient", LOG_LEVEL_WARNING); 01274 return m_ssl_ctx; 01275 }
SSL * TcpSocket::GetSsl | ( | ) | [protected, virtual] |
SSL; Get pointer to ssl structure.
Reimplemented from Socket.
Definition at line 1277 of file TcpSocket.cpp.
References Socket::Handler(), LOG_LEVEL_WARNING, ISocketHandler::LogError(), and m_ssl.
01278 { 01279 if (!m_ssl) 01280 Handler().LogError(this, "GetSsl", 0, "SSL is NULL; check InitSSLServer/InitSSLClient", LOG_LEVEL_WARNING); 01281 return m_ssl; 01282 }
bool TcpSocket::SSLNegotiate | ( | ) | [protected, virtual] |
ssl; still negotiating connection.
Reimplemented from Socket.
Definition at line 1076 of file TcpSocket.cpp.
References DEB, GetOutputLength(), Socket::Handler(), IsReconnect(), Socket::IsSSLServer(), LOG_LEVEL_INFO, ISocketHandler::LogError(), m_ssl, Socket::OnAccept(), Socket::OnConnect(), Socket::OnReconnect(), Socket::OnSSLAcceptFailed(), Socket::OnSSLConnectFailed(), OnWrite(), Socket::SetCloseAndDelete(), Socket::SetConnected(), Socket::SetNonblocking(), and Socket::SetSSLNegotiate().
01077 { 01078 if (!IsSSLServer()) // client 01079 { 01080 int r = SSL_connect(m_ssl); 01081 if (r > 0) 01082 { 01083 SetSSLNegotiate(false); 01085 // CheckCertificateChain( "");//ServerHOST); 01086 SetNonblocking(false); 01087 // 01088 { 01089 SetConnected(); 01090 if (GetOutputLength()) 01091 { 01092 OnWrite(); 01093 } 01094 } 01095 #ifdef ENABLE_RECONNECT 01096 if (IsReconnect()) 01097 OnReconnect(); 01098 else 01099 #endif 01100 { 01101 OnConnect(); 01102 } 01103 Handler().LogError(this, "SSLNegotiate/SSL_connect", 0, "Connection established", LOG_LEVEL_INFO); 01104 return true; 01105 } 01106 else 01107 if (!r) 01108 { 01109 Handler().LogError(this, "SSLNegotiate/SSL_connect", 0, "Connection failed", LOG_LEVEL_INFO); 01110 SetSSLNegotiate(false); 01111 SetCloseAndDelete(); 01112 OnSSLConnectFailed(); 01113 } 01114 else 01115 { 01116 r = SSL_get_error(m_ssl, r); 01117 if (r != SSL_ERROR_WANT_READ && r != SSL_ERROR_WANT_WRITE) 01118 { 01119 Handler().LogError(this, "SSLNegotiate/SSL_connect", -1, "Connection failed", LOG_LEVEL_INFO); 01120 DEB( fprintf(stderr, "SSL_connect() failed - closing socket, return code: %d\n",r);) 01121 SetSSLNegotiate(false); 01122 SetCloseAndDelete(true); 01123 OnSSLConnectFailed(); 01124 } 01125 } 01126 } 01127 else // server 01128 { 01129 int r = SSL_accept(m_ssl); 01130 if (r > 0) 01131 { 01132 SetSSLNegotiate(false); 01134 // CheckCertificateChain( "");//ClientHOST); 01135 SetNonblocking(false); 01136 // 01137 { 01138 SetConnected(); 01139 if (GetOutputLength()) 01140 { 01141 OnWrite(); 01142 } 01143 } 01144 OnAccept(); 01145 Handler().LogError(this, "SSLNegotiate/SSL_accept", 0, "Connection established", LOG_LEVEL_INFO); 01146 return true; 01147 } 01148 else 01149 if (!r) 01150 { 01151 Handler().LogError(this, "SSLNegotiate/SSL_accept", 0, "Connection failed", LOG_LEVEL_INFO); 01152 SetSSLNegotiate(false); 01153 SetCloseAndDelete(); 01154 OnSSLAcceptFailed(); 01155 } 01156 else 01157 { 01158 r = SSL_get_error(m_ssl, r); 01159 if (r != SSL_ERROR_WANT_READ && r != SSL_ERROR_WANT_WRITE) 01160 { 01161 Handler().LogError(this, "SSLNegotiate/SSL_accept", -1, "Connection failed", LOG_LEVEL_INFO); 01162 DEB( fprintf(stderr, "SSL_accept() failed - closing socket, return code: %d\n",r);) 01163 SetSSLNegotiate(false); 01164 SetCloseAndDelete(true); 01165 OnSSLAcceptFailed(); 01166 } 01167 } 01168 } 01169 return false; 01170 }
const std::string & TcpSocket::GetPassword | ( | ) | [protected] |
SSL; Get ssl password.
Definition at line 1350 of file TcpSocket.cpp.
References m_password.
Referenced by SSL_password_cb().
01351 { 01352 return m_password; 01353 }
CircularBuffer TcpSocket::ibuf [protected] |
Circular input buffer.
Definition at line 211 of file TcpSocket.h.
Referenced by GetInputLength(), OnRead(), and OnSocks4Read().
CircularBuffer TcpSocket::obuf [protected] |
Circular output buffer.
Definition at line 212 of file TcpSocket.h.
Referenced by GetOutputLength(), OnWrite(), and SendBuf().
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 219 of file TcpSocket.h.
Referenced by OnRead().
char TcpSocket::m_c [private] |
First char in CRLF or LFCR sequence.
Definition at line 220 of file TcpSocket.h.
Referenced by OnRead().
std::string TcpSocket::m_line [private] |
Current line in line protocol mode.
Reimplemented in HTTPSocket.
Definition at line 221 of file TcpSocket.h.
Referenced by OnRead().
ucharp_v TcpSocket::m_mes [private] |
overflow protection, dynamic output buffer
Definition at line 222 of file TcpSocket.h.
Referenced by OnWrite(), SendBuf(), and ~TcpSocket().
char* TcpSocket::m_buf [private] |
temporary read buffer
Definition at line 224 of file TcpSocket.h.
Referenced by OnRead(), and ~TcpSocket().
SSLInitializer TcpSocket::m_ssl_init [static, private] |
Definition at line 228 of file TcpSocket.h.
SSL_CTX* TcpSocket::m_ssl_ctx [private] |
ssl context
Definition at line 229 of file TcpSocket.h.
Referenced by GetSslContext(), InitializeContext(), OnSSLAccept(), and OnSSLConnect().
SSL* TcpSocket::m_ssl [private] |
ssl 'socket'
Definition at line 230 of file TcpSocket.h.
Referenced by Close(), GetSsl(), OnRead(), OnSSLAccept(), OnSSLConnect(), OnWrite(), SSLNegotiate(), and ~TcpSocket().
BIO* TcpSocket::m_sbio [private] |
ssl bio
Definition at line 231 of file TcpSocket.h.
Referenced by OnSSLAccept(), and OnSSLConnect().
std::string TcpSocket::m_password [private] |
ssl password
Definition at line 232 of file TcpSocket.h.
Referenced by GetPassword(), and InitializeContext().
int TcpSocket::m_socks4_state [private] |
socks4 support
Definition at line 236 of file TcpSocket.h.
Referenced by OnSocks4Connect(), and OnSocks4Read().
char TcpSocket::m_socks4_vn [private] |
socks4 support, temporary variable
Definition at line 237 of file TcpSocket.h.
Referenced by OnSocks4Read().
char TcpSocket::m_socks4_cd [private] |
socks4 support, temporary variable
Definition at line 238 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 244 of file TcpSocket.h.
Referenced by OnResolved(), and Open().
bool TcpSocket::m_b_reconnect [private] |
Reconnect on lost connection flag.
Definition at line 248 of file TcpSocket.h.
Referenced by Reconnect(), and SetReconnect().
bool TcpSocket::m_b_is_reconnect [private] |
Trying to reconnect.
Definition at line 249 of file TcpSocket.h.
Referenced by IsReconnect(), and SetIsReconnect().