2011-07-07 30 views
7

Este código es para un servidor HTTPS utilizando sockets de bloqueo:¿Por qué esta llamada SSL_pending siempre devuelve cero?

request := ''; 
    start := gettickcount; 
    repeat 
    if SSL_pending(ssl) > 0 then 
     begin 
     bytesin := SSL_read(ssl, buffer, sizeof(buffer)-1); 
     if bytesin > 0 then 
     begin 
     buffer[bytesin] := #0; 
     request := request + buffer; 
     end 
     else break; // read failed 
     end; // pending 
    until (gettickcount - start) > LARGETIMEOUT; 
    // "request" is ready, though possibly empty 

SSL_pending() siempre devuelve cero y nunca se alcanza el SSL_read(). Si se elimina la llamada SSL_pending(), se ejecuta SSL_read(). ¿Por qué SSL_pending() indica cuántos bytes están disponibles?

Tenga en cuenta que si llama a SSL_read() y el número de bytes devueltos es menor que el tamaño de su búfer, ha leído todo y listo.

Si los datos entrantes son más grandes que su tamaño de búfer, la primera llamada SSL_read() llena el búfer y puede repetir la llamada SSL_read() hasta que no pueda llenar el búfer.

PERO si los datos entrantes son un múltiplo exacto de su tamaño de búfer, el último fragmento de datos llena el búfer. Si intenta otro SSL_read() pensando que podría haber más datos en un socket de bloqueo, se bloquea indefinidamente. De ahí el deseo de verificar SSL_pending() primero. Sin embargo, eso no parece funcionar.

¿Cómo se evita colgar en un SSL_read final()? (No me puedo imaginar la respuesta es ir sin bloqueo, ya que eso significa que nunca podría usar SSL_read con el bloqueo.)

ACTUALIZACIÓN: La siguiente funciona. Al parecer SSL_pending() no funciona hasta después del primer SSL_read():

request := ''; 
    repeat 
    bytesin := SSL_read(ssl, buffer, sizeof(buffer)-1); 
    if bytesin > 0 then 
     begin 
     buffer[bytesin] := #0; 
     request := request + buffer; 
     end 
    else break; // read failed 
    until SSL_pending(ssl) <= 0; 
    // "request" is ready, though possibly empty 

Respuesta

5

está usando el SSL_pending() el camino completamente equivocado. OpenSSL utiliza una máquina de estados, donde SSL_pending() indica si la máquina de estados tiene bytes pendientes que han sido almacenados temporalmente y están a la espera del procesamiento. Como nunca llama al SSL_read(), nunca está guardando en búfer ningún dato o avanzando en la máquina de estado.

+7

La documentación para SSL_pending no lo deja claro. –

+0

Algo así como: "obtener el número de bytes legibles almacenados en un objeto SSL ... los datos pueden almacenarse en ssl y están listos para su recuperación inmediata con SSL_read (3)" –

2

Si la función SSL_pending devuelve un código de retorno de 0, no significa necesariamente que no haya datos disponibles inmediatamente para leer en la sesión SSL. Un código de retorno de 0 indica que no hay más datos en el registro de datos SSL actual. Sin embargo, es posible que se hayan recibido más registros de datos SSL de la red. Si la función SSL_pending devuelve un código de retorno de 0, emita la función de selección, pasando el descriptor de archivo del socket para verificar si el socket es legible. Legible significa que se han recibido más datos de la red en el socket.

Cuestiones relacionadas