Hallo We habe a problem with our c++ win32 application. We are using WinSockets and write/read data with openssl. 95% are working fine. But when the response takes longer, the application is blocked.
Now i've try to make the socket non-blocked, but it doesen't works. Here are a few code-lines of our application: ... m_client = new TClientSocket(Application->MainForm); m_client->ClientType = ctNonBlocking; (we are using non-blocking sockets) ... nt __fastcall TcpFeSession::InitCTX() { int sslStatus = 0; AnsiString sslIniFile = FOSUP_SSL_CONFIG_FILE; // Init. globale Informationen SSL_library_init(); SSL_load_error_strings(); // Erstellung des context meth = TLSv1_method(); ctx = SSL_CTX_new(meth); if (ctx == NULL) { m_foRegistry->LOG_INFO("ERROR: InitCTX -> SSL_CTX_new() failed..."); return -1; } ERR_clear_error(); sslStatus = SSL_CTX_load_verify_locations(ctx, sslIniFile.c_str(), CADIR); if (!sslStatus) { m_foRegistry->LOG_INFO("ERROR: InitCTX -> SSL_CTX_load_verify_locations(" + sslStatus + ") ..."); return -1; } sslStatus = SSL_CTX_set_default_verify_paths(ctx); if (!sslStatus) { m_foRegistry->LOG_INFO("ERROR: InitCTX -> SSL_CTX_set_default_verify_paths(" + sslStatus + ") ..."); return -1; } SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, &TcpFeSession::verify_callback); SSL_CTX_set_verify_depth(ctx, 4); SSL_CTX_set_options(ctx, SSL_OP_ALL); sslStatus = SSL_CTX_set_cipher_list(ctx, CIPHER_LIST); if ( !sslStatus) { m_foRegistry->LOG_ERROR("ERROR: InitCTX -> SSL_CTX_set_cipher_list() " + SSL_get_error(ssl, sslStatus) + " ..."); return -1; } m_foRegistry->LOG_INFO("INFO: SSL InitCTX -> successful..."); return 1; } int __fastcall TcpFeSession::OpenSSL(TCustomWinSocket *Socket) { int sslStatus = 0; int sslError = 0; int extcount; int sock; u_long nonblocking = 1; std::string sHost = m_client->Host.c_str(); std::ostringstream oss; oss << sHost << ":" << m_client->Port; std::string myConnect(oss.str()); // SSL Struktur erstellen ssl = SSL_new(ctx); if ( !ssl ) { m_foRegistry->LOG_ERROR("ERROR: OpenSSL -> SSL_new() ..."); return -1; } // Neue Verbindung erstellen conn = BIO_new_connect(const_cast<char*>(myConnect.c_str())); if (!conn) { m_foRegistry->LOG_ERROR("ERROR: OpenSSL -> BIO_new_connect() ..."); return -1; } if (BIO_do_connect(conn) <= 0) { m_foRegistry->LOG_ERROR("ERROR: OpenSSL -> BIO_do_connect() ..."); return -1; } BIO_set_fd(conn, sock, BIO_NOCLOSE); SSL_set_bio(ssl, conn, conn); // If the socket is in non-blocking mode set the BIO // to non-blocking mode (blocking is the default) // Set both the read and write BIO's to non-blocking mode BIO_set_nbio(SSL_get_rbio(ssl), 1); BIO_set_nbio(SSL_get_wbio(ssl), 1); // Connecting / Handshake sslStatus = SSL_connect(ssl); sslError = SSL_get_error(ssl, sslStatus); switch(sslError) { case SSL_ERROR_ZERO_RETURN: m_foRegistry->LOG_ERROR("ERROR: OpenSSL -> SSL_connect() peer close ssl connection ..."); return -1; default: break; } // SSL_set_connect_state(ssl); // START: Server Zertikikat annehmen server_cert = SSL_get_peer_certificate(ssl); if ( !server_cert ) { m_foRegistry->LOG_INFO("INFO: OpenSSL -> SSL_get_peer_certificate() The SSL server does not have certificate..."); } if(SSL_get_verify_result(ssl) != X509_V_OK) { m_foRegistry->LOG_ERROR("ERROR: OpenSSL -> SSL_get_verify_result() ..."); return -1; } m_foRegistry->LOG_INFO("INFO: OpenSSL successful..."); return 1; } void __fastcall TcpFeSession::ClientRead(TObject *Sender, TCustomWinSocket *Socket) { int readCount; ... unsigned nread; for (nread = 0; nread < bytesToRead; nread += readCount) { unsigned remaining = std::min(bytesToRead - nread, 4088u); while (0 >= (readCount = SSL_read(ssl, readBuffer + nread, remaining))){ switch (SSL_get_error(ssl, readCount)) { case SSL_ERROR_NONE: m_foRegistry->LOG_INFO("INFO: ClientRead -> SSL_read() Header successful (" + readCount + ")..."); break; case SSL_ERROR_WANT_WRITE: m_foRegistry->LOG_ERROR("ERROR: ClientRead -> SSL_read( " + readCount + " ) Header failed (write W BLOCK) ..."); break; case SSL_ERROR_WANT_READ: m_foRegistry->LOG_ERROR("ERROR: ClientRead -> SSL_read( " + readCount + " ) Header failed (write R BLOCK) ..."); break; case SSL_ERROR_WANT_X509_LOOKUP: m_foRegistry->LOG_ERROR("ERROR: ClientRead -> SSL_read( " + readCount + " ) Header failed (write X BLOCK) ..."); break; case SSL_ERROR_ZERO_RETURN: m_foRegistry->LOG_ERROR("ERROR: ClientRead -> SSL_read( " + readCount + " ) Header failed (shutdown) ..."); break; case SSL_ERROR_SYSCALL: m_foRegistry->LOG_ERROR("ERROR: ClientRead -> SSL_read( " + readCount + " ) Header failed (write socket error) ..."); break; case SSL_ERROR_SSL: m_foRegistry->LOG_ERROR("ERROR: ClientRead -> SSL_read( " + readCount + " ) Header failed (ssl error) ..."); break; default: break; } } if (readCount <= 0) break; Application->ProcessMessages(); } ... Now my question! What i must done, that the ssl_read function dosent blocked. I've try to make a select(), or using ssl_pending() and many other things, but nothing works? Please can you help me? Best regards, Dirk --------------------------------------------------------------------------- Telekurs Card Solutions AG Dirk Platte Karl Neuhaus-Strasse 40 CH-2502 Biel Tel.: +41 32 328 78 69 Fax: +41 32 328 78 12 Mobile: +41 79 287 12 74 E-Mail: [EMAIL PROTECTED] WWW: www.telekurs-card-solution.ch --------------------------------------------------------------------------- This e-mail may contain confidential and privileged information. If you are not the intended recipient, please notify the sender and delete this e-mail immediately.