使用select和多个阻塞套接字重新协商OpenSSL



我有一个使用多个阻塞套接字的服务器线程,我需要在有数据要处理时运行它。问题是,如何让OpenSSL在不陷入阻塞操作(等待应用程序数据)的情况下完成"它的工作"(如重新协商)?注意:我有SSL_set_mode - SSL_MODE_AUTO_RETRY,我怀疑我不需要这样做,而是自己处理这些案例,但从阅读文档中还不清楚我将如何做到这一点。考虑以下伪代码:

while(running){
    select on readability sockets 1 and 2
    if(socket 1 readable) {
        SSL_read data(socket 1)
        process data, possibly interacting with socket 2
    }
    if(socket 2 readable) {
        SSL_read data(socket 2)
        process data, possibly interacting with socket 1
    }
}

如果由于套接字上有SSL/TLS层"要做的事情"而没有应用程序层数据,所以选择退出,会发生什么?SSL_read将处理"要做的事情",但由于没有应用程序数据而阻止。。。该块会扼杀从另一个套接字读取的能力。有一个很好的方法SSL_pending可以告诉我应用程序数据,但据我所知,如果没有SSL_read,堆栈就没有机会获得任何数据。除了将套接字分离成单独的线程或使用非阻塞套接字之外,是否有一种简单的方法可以对OpenSSL层说"如果需要,请重新协商,如果有,则读取数据记录,如果两者都不需要,则不阻塞"类似于NULL/NULL读取或写入?

// process records on the socket
SSL_read( ssl, 0, 0 ); // or maybe SSL_write( ssl, 0, 0 ) ?
if ( SSL_pending( ssl ) ) {
    // do the application data read
    SSL_read( ssl, buf, sizeof(buf) );
}

编辑:尝试在不选择读取的情况下执行SSL_read( ssl, 0, 0 ),它会阻塞一条记录,因此无法工作。进行select然后read-0/0或SSL_write( ssl, 0, 0 )而不进行select似乎不是阻塞,尽管我还不确定这两者是否都在做我需要做的事情…

SSL_Pending用于预读,而不是用于您正在使用的目的。当完成下一次读取时,阻止读取将自动重新协商。如果您使用的是ssl_set_fd,您可以在描述符上设置接收超时,在这种情况下它可能会对您有所帮助。当进行多个连接时,如何在C中设置套接字超时?

否则可以使用非阻塞io。

最新更新