static int s_sockexClose( PHB_SOCKEX pSock, HB_BOOL fClose ) { int iResult; if( pSock->cargo ) hb_ssl_socketClose( HB_SSLSOCK_GET( pSock ) ); iResult = hb_sockexRawClear( pSock, fClose ); hb_xfree( pSock ); return iResult; }
PHB_SSLSTREAM hb_ssl_socketNew( HB_SOCKET sd, SSL * ssl, HB_BOOL fServer, HB_MAXINT timeout, PHB_ITEM pSSL, int * piResult ) { int iResult; PHB_SSLSTREAM pStream; HB_MAXUINT timer; pStream = ( HB_SSLSTREAM * ) hb_xgrabz( sizeof( HB_SSLSTREAM ) ); timer = timeout <= 0 ? 0 : hb_dateMilliSeconds(); pStream->ssl = ssl; pStream->pSSL = pSSL ? hb_itemNew( pSSL ) : NULL; pStream->blocking = timeout < 0; if( hb_socketSetBlockingIO( sd, pStream->blocking ) < 0 ) pStream->blocking = ! pStream->blocking; SSL_set_mode( ssl, HB_SSL_MODE_AUTO_RETRY ); iResult = SSL_set_fd( ssl, sd ); /* Truncates `sd` on win64. OpenSSL bug: https://rt.openssl.org/Ticket/Display.html?id=1928&user=guest&pass=guest */ while( iResult == 1 ) { if( fServer ) iResult = SSL_accept( ssl ); else iResult = SSL_connect( ssl ); if( iResult != 1 && hb_vmRequestQuery() == 0 ) { int iError = SSL_get_error( ssl, iResult ); if( iError == SSL_ERROR_WANT_READ || iError == SSL_ERROR_WANT_WRITE ) { if( timeout < 0 ) { iResult = 1; continue; } else if( timeout > 0 ) { HB_MAXUINT timecurr = hb_dateMilliSeconds(); if( timecurr > timer ) { timeout -= timecurr - timer; if( timeout < 0 ) timeout = 0; timer = timecurr; } if( timeout > 0 ) { if( iError == SSL_ERROR_WANT_READ ) iError = hb_socketSelectRead( sd, timeout ); else iError = hb_socketSelectWrite( sd, timeout ); if( iError > 0 ) { iResult = 1; continue; } } } hb_socketSetError( HB_SOCKET_ERR_TIMEOUT ); } } break; } if( iResult != 1 ) { hb_ssl_socketClose( pStream ); pStream = NULL; } else pStream->blocking = hb_socketSetBlockingIO( sd, HB_FALSE ) < 0; if( piResult ) *piResult = iResult; return pStream; }
PHB_SSLSTREAM hb_ssl_socketNew( HB_SOCKET sd, SSL * ssl, HB_BOOL fServer, HB_MAXINT timeout, int * piResult ) { int iResult; PHB_SSLSTREAM pStream; HB_MAXUINT timer; pStream = ( HB_SSLSTREAM * ) hb_xgrabz( sizeof( HB_SSLSTREAM ) ); timer = timeout <= 0 ? 0 : hb_dateMilliSeconds(); pStream->ssl = ssl; pStream->pSSL = hb_itemNew( hb_param( 2, HB_IT_POINTER ) ); pStream->blocking = timeout < 0; if( hb_socketSetBlockingIO( sd, pStream->blocking ) < 0 ) pStream->blocking = ! pStream->blocking; SSL_set_mode( ssl, HB_SSL_MODE_AUTO_RETRY ); iResult = SSL_set_fd( ssl, sd ); while( iResult == 1 ) { if( fServer ) iResult = SSL_accept( ssl ); else iResult = SSL_connect( ssl ); if( iResult != 1 && hb_vmRequestQuery() == 0 ) { int iError = SSL_get_error( ssl, iResult ); if( iError == SSL_ERROR_WANT_READ || iError == SSL_ERROR_WANT_WRITE ) { if( timeout < 0 ) { iResult = 1; continue; } else if( timeout > 0 ) { HB_MAXUINT timecurr = hb_dateMilliSeconds(); if( timecurr > timer ) { timeout -= timecurr - timer; timer = timecurr; } if( timeout > 0 ) { if( iError == SSL_ERROR_WANT_READ ) iError = hb_socketSelectRead( sd, timeout ); else iError = hb_socketSelectWrite( sd, timeout ); if( iError > 0 ) { iResult = 1; continue; } } } hb_socketSetError( HB_SOCKET_ERR_TIMEOUT ); } } break; } if( iResult != 1 ) { hb_ssl_socketClose( pStream ); pStream = NULL; } else pStream->blocking = hb_socketSetBlockingIO( sd, HB_FALSE ) < 0; if( piResult ) *piResult = iResult; return pStream; }