使用选择和多个阻塞套接字进行OpenSSL重新协商

使用选择和多个阻塞套接字进行OpenSSL重新协商,openssl,Openssl,我有一个使用多个阻塞套接字的服务器线程,需要在有数据要处理时运行它。问题是,我如何让OpenSSL做“它的事情”(比如重新协商),而不陷入阻塞操作(等待应用程序数据)?注意:我有SSL\u set\u mode-SSL\u mode\u AUTO\u RETRY,我怀疑我不需要这样做,而是自己处理这些案例,但阅读文档不清楚我将如何做到这一点。考虑下面的伪代码: while(running){ select on readability sockets 1 and 2 if(soc

我有一个使用多个阻塞套接字的服务器线程,需要在有数据要处理时运行它。问题是,我如何让OpenSSL做“它的事情”(比如重新协商),而不陷入阻塞操作(等待应用程序数据)?注意:我有
SSL\u set\u mode-SSL\u mode\u AUTO\u 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
    }
}
如果select退出是因为在任一套接字上都有SSL/TLS层“要做的事情”,而不是应用层数据,会发生什么情况
SSL\u read
将处理“要做的事情”,但由于没有应用程序数据,因此会被阻止。。。该块终止了从另一个套接字读取的能力。有一种很好的方法
SSL\u pending
可以告诉我有关应用程序数据的信息,但据我所知,如果没有
SSL\u读取
,堆栈就没有机会获取任何数据。除了将套接字分离为单独的线程或使用非阻塞套接字之外,是否有一种简单的方法可以对OpenSSL层说“如果需要,请重新协商,如果有数据记录,请读取数据记录,如果不需要,则不阻塞”类似于空/空读或写

// 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\u读取(SSL,0,0)
,它会阻止记录,因此无法正常工作。在没有select的情况下执行select then read-0/0或
SSL\u write(SSL,0,0)
似乎并没有阻塞,尽管我还不确定这两种方法是否都在执行我需要它执行的操作

SSL_Pending用于预读,而不是用于您正在使用的目的。当下一次读取完成时,阻塞读取将自动重新协商。如果您使用的是ssl\u set\u fd,您可以在描述符上设置接收超时,在这种情况下它可能会对您有所帮助。


否则,可以使用非阻塞io。

SSL\u挂起用于预读,而不是用于您正在使用的目的。当下一次读取完成时,阻塞读取将自动重新协商。如果您使用的是ssl\u set\u fd,您可以在描述符上设置接收超时,在这种情况下它可能会对您有所帮助。否则可以使用非阻塞io。谢谢。。。我在两个套接字上都使用了
SSL\u set\u fd
,我在两个套接字上都使用了
select
,并且超时。我的问题是,当select指示套接字需要读取时,我如何知道数据是否是重新协商的(非应用程序数据)?如果不是应用程序数据,那么一个
SSL\u read
可以很好地进行重新协商,但是它会阻塞应用程序数据,这就是问题所在。您需要在fd上设置SO_RCVTIMEO和SO_SNDTIMEO,当SSL_读取完成协商时,它将在上述调用中设置的超时后返回,因此您不需要担心始终等待读取部分。请不要,我不是指select上的超时,而是fd上的超时。啊,我想你是在建议继续,让它阻塞,只使用接近零的东西…是的,有一个select,它会告诉你有东西要读,万一it应用程序数据都好的话。如果是重新协商,它将执行该操作,然后可能继续读取,该操作将在最初使用set_sock_opt指定的超时时间返回。您可以将其设置为接近零的值。从Windows文档中可以看出,这听起来不祥:如果套接字上的发送或接收操作超时,则套接字状态不确定,不应使用。请注意,我需要能够继续使用连接,我并没有中止它。我需要进一步研究这个。。。