2012-04-24 11 views
6

Tengo una biblioteca de red TCP que implementa un grupo de protocolos (redis, http, etc.) y se implementan usando sockets BSD.Integrando SSL en un programa que usa conectores BSD

Una gran parte del código utiliza select() y otras funciones que están destinadas a conectores BSD. ¿Estoy en lo cierto al suponer que esto no funcionará en los sockets SSL? ¿O van a funcionar como están?

Me pregunto si los zócalos SSL y BSD son tan diferentes que requieren un enfoque completamente diferente para la implementación.

+1

La comunicación SSL usa conectores "BSD" normales, es solo otro nivel de protocolo encima, p. Ej. TCP. –

Respuesta

6

Suponiendo que se refiere a OpenSSL, se encuentra en la parte superior del zócalo, no lo reemplaza. Así que todas las operaciones de socket directo, como select(), todavía funcionan. La diferencia, sin embargo, es que OpenSSL maneja la lectura y la escritura para que pueda reemplazar recv() con ssl_read() y send() con ssl_write(), pero puede (y en algunos casos lo necesita) seguir usando select() directamente. Sin embargo, no puede simplemente llamar cuando lo desee, debe esperar hasta que OpenSSL le indique que lo llame. Entonces, por ejemplo, si tiene un bucle de lectura que llama primero al select() y luego llama al recv() solo cuando select() informe la legibilidad, tendría que cambiar esa lógica. ssl_read() llamar primero, y luego llamar a select() sólo si devuelve o ssl_read()SSL_ERROR_WANT_READ o SSL_ERROR_WANT_WRITE (tenga en cuenta que ssl_read() puede realizar operaciones de escritura internamente y ssl_write() puede realizar operaciones de lectura internamente).

2

Una cosa que le viene a la mente es que no debe hacer una selección en el fd a través del cual se ejecuta la conexión ssl. Esto se debe a que podría, por ejemplo, decir que puede leer de él mientras se bloquea el ssl_read. Eso es causado, por ejemplo, por SSL haciendo una renegociación de claves y no por datos de aplicaciones para estar disponibles. Ese es uno de los pitfals.

+1

en realidad, select() todavía se usa, pero la lógica del protocolo debe verificar no seleccionar() sino la disponibilidad de datos decodificados en el búfer. –

0

Esto puede ser tarde, pero puede servir como una buena referencia para futuros usuarios. Hay un buen hilo sobre el uso de la función select() en la url http://developerweb.net/viewtopic.php?id=6824. Un ejemplo citado es la siguiente

int sslsock_handle_nbio (ssl, ret, totv) 
    void   *ssl;   /* -> the SSL info      */ 
    int    ret;   /* the SSL I/O function return value */ 
    struct timeval *totv;   /* -> timeout info, or NULL    */ 
{ 
    int  sfd, i; 
    fd_set rset, wset; 

    sfd = SSL_get_fd (ssl); 
    i = SSL_get_error (ssl, ret); 

    if (i == SSL_ERROR_WANT_READ) { 
    do { 
     FD_ZERO (&rset); 
     FD_SET (sfd, &rset); 
     i = select (sfd + 1, &rset, NULL, NULL, totv); 
    } while ((i < 0) && (errno == EINTR)); 
    if (i == 0) { 
     /* the select() timed out */ 
     ret = -2; 
     errno = ETIMEDOUT; 
    } else { 
     /* either an error, or it's readable */ 
     ret = i; 
    } 
    } else if (i == SSL_ERROR_WANT_WRITE) { 
    do { 
     FD_ZERO (&wset); 
     FD_SET (sfd, &wset); 
     i = select (sfd + 1, NULL, &wset, NULL, totv); 
    } while ((i < 0) && (errno == EINTR)); 
    if (i == 0) { 
     /* the select() timed out */ 
     ret = -2; 
     errno = ETIMEDOUT; 
    } else { 
     /* either an error, or it's writable */ 
     ret = i; 
    } 
    } 
    /* else, leave "ret" alone, and return it as-is */ 

    return (ret); 
} 

Esta es sólo después de realizar SSL_read() o SSL_write().

Cuestiones relacionadas