Exemple #1
0
static int s_sockexCanRead( PHB_SOCKEX pSock, HB_BOOL fBuffer, HB_MAXINT timeout )
{
   if( pSock->inbuffer )
      return 1;
   else if( pSock->sd == HB_NO_SOCKET )
   {
      hb_socketSetError( HB_SOCKET_ERR_INVALIDHANDLE );
      return -1;
   }
   else if( SSL_pending( HB_SSLSOCK_GET( pSock )->ssl ) )
   {
      long len;

      if( pSock->buffer == NULL )
      {
         if( pSock->readahead <= 0 )
            pSock->readahead = HB_SSLSOCK_READAHEAD;
         pSock->buffer = ( HB_BYTE * ) hb_xgrab( pSock->readahead );
      }
      len = hb_ssl_socketRead( HB_SSLSOCK_GET( pSock ), pSock->sd,
                               pSock->buffer, pSock->readahead, 0 );
      if( len > 0 )
      {
         pSock->inbuffer = len;
         len = 1;
      }
      return ( int ) len;
   }
   return fBuffer ? 0 : hb_socketSelectRead( pSock->sd, timeout );
}
Exemple #2
0
/* check if data can be read from extended socket,
   return 1, 0 or -1 to indicate error.
   If fBuffer parameter is set to true then only data already read
   from socket and stored in memory buffer should be checked without
   any timeout. Such call is executed just before inside
   hb_sockexSelect() just before call to low level socket select()
   function. */
static int s_sockexCanRead( PHB_SOCKEX pSock, HB_BOOL fBuffer, HB_MAXINT timeout )
{
   if( pSock->inbuffer > 0 )
      return 1;
   else if( pSock->sd == HB_NO_SOCKET )
   {
      hb_socketSetError( HB_SOCKET_ERR_INVALIDHANDLE );
      return -1;
   }
   return fBuffer ? 0 : hb_socketSelectRead( pSock->sd, timeout );
}
Exemple #3
0
long hb_ssl_socketRead( PHB_SSLSTREAM pStream, HB_SOCKET sd,
                        void * buffer, long len, HB_MAXINT timeout )
{
   HB_MAXUINT timer = timeout <= 0 ? 0 : hb_dateMilliSeconds();
   long lRead = -1;
   int iToRead = -1;

   /* sd = SSL_get_rfd( pStream->ssl ); */

#if LONG_MAX > INT_MAX
   if( len > INT_MAX )
      len = INT_MAX;
#endif

#if 0
   while( ERR_get_error() != 0 ) { /* eat pending errors */ }
#endif

   if( pStream->blocking ? timeout >= 0 : timeout < 0 )
   {
      if( hb_socketSetBlockingIO( sd, timeout < 0 ) >= 0 )
         pStream->blocking = ! pStream->blocking;
   }

   if( len > 0 )
   {
      iToRead = SSL_pending( pStream->ssl );
      if( iToRead <= 0 )
      {
         iToRead = timeout < 0 ? 1 : hb_socketSelectRead( sd, timeout );
         if( iToRead > 0 )
            iToRead = ( int ) len;
         else if( iToRead == 0 )
            hb_socketSetError( HB_SOCKET_ERR_TIMEOUT );
      }
      else if( iToRead > len )
         iToRead = ( int ) len;
   }

   while( iToRead > 0 )
   {
      lRead = SSL_read( pStream->ssl, buffer, iToRead );
      if( lRead > 0 )
         hb_socketSetError( 0 );
      else
      {
         int iError = SSL_get_error( pStream->ssl, ( int ) lRead );
         switch( iError )
         {
            case SSL_ERROR_ZERO_RETURN:
               hb_socketSetError( HB_SOCKET_ERR_PIPE );
               lRead = 0;
               break;
            case SSL_ERROR_WANT_READ:
            case SSL_ERROR_WANT_WRITE:
               if( hb_vmRequestQuery() == 0 )
               {
                  if( timeout > 0 )
                  {
                     HB_MAXUINT timecurr = hb_dateMilliSeconds();
                     if( timecurr > timer )
                        timeout -= timecurr - timer;
                     if( timeout > 0 )
                     {
                        timer = timecurr;
                        if( iError == SSL_ERROR_WANT_READ )
                           iError = hb_socketSelectRead( sd, timeout );
                        else
                           iError = hb_socketSelectWrite( sd, timeout );
                        if( iError > 0 )
                           continue;
                        else if( iError < 0 )
                           break;
                     }
                  }
                  hb_socketSetError( HB_SOCKET_ERR_TIMEOUT );
                  break;
               }
            default:
               hb_socketSetError( HB_SSL_SOCK_ERROR_BASE + iError );
         }
      }
      break;
   }

   return lRead;
}
Exemple #4
0
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;
}
Exemple #5
0
long hb_ssl_socketWrite( PHB_SSLSTREAM pStream, HB_SOCKET sd,
                         const void * buffer, long len, HB_MAXINT timeout,
                         long * plast )
{
   HB_MAXUINT timer = timeout <= 0 ? 0 : hb_dateMilliSeconds();
   long lWritten = 0, lWr = 0;

   /* sd = SSL_get_wfd( pStream->ssl ); */

#if LONG_MAX > INT_MAX
   if( len > INT_MAX )
      len = INT_MAX;
#endif

#if 0
   while( ERR_get_error() != 0 ) { /* eat pending errors */ }
#endif

   if( pStream->blocking ? timeout >= 0 : timeout < 0 )
   {
      if( hb_socketSetBlockingIO( sd, timeout < 0 ) >= 0 )
         pStream->blocking = ! pStream->blocking;
   }

   while( len > 0 )
   {
      lWr = SSL_write( pStream->ssl, buffer, ( int ) len );

      if( plast )
         *plast = lWr;

      if( lWr > 0 )
      {
         lWritten += lWr;
         len -= lWr;
         buffer = ( const char * ) buffer + lWr;
         hb_socketSetError( 0 );
      }
      else
      {
         int iError = SSL_get_error( pStream->ssl, ( int ) lWr );
         switch( iError )
         {
            case SSL_ERROR_WANT_READ:
            case SSL_ERROR_WANT_WRITE:
               if( hb_vmRequestQuery() == 0 )
               {
                  if( timeout > 0 )
                  {
                     HB_MAXUINT timecurr = hb_dateMilliSeconds();
                     if( timecurr > timer )
                        timeout -= timecurr - timer;
                     if( timeout > 0 )
                     {
                        timer = timecurr;
                        if( iError == SSL_ERROR_WANT_READ )
                           iError = hb_socketSelectRead( sd, timeout );
                        else
                           iError = hb_socketSelectWrite( sd, timeout );
                        if( iError > 0 )
                           continue;
                     }
                     else
                        iError = 0;
                  }
                  else
                     iError = 0;
                  if( lWritten == 0 && iError == 0 )
                     hb_socketSetError( HB_SOCKET_ERR_TIMEOUT );
                  break;
               }
            default:
               hb_socketSetError( HB_SSL_SOCK_ERROR_BASE + iError );
         }
         break;
      }
   }

   return lWritten != 0 ? lWritten : lWr;
}
Exemple #6
0
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;
}