我有一个使用多个阻塞套接字的服务器线程,我需要在需要处理的数据时运行它。问题是,我如何让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层说明如果需要的话,可以像那样进行重新协商,如果有的话,还可以读取数据记录。 t block如果不需要“?像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) );
}
编辑:尝试在没有select-read的情况下执行SSL_read( ssl, 0, 0 )
并阻止记录,以便无效。选择然后读取0/0或SSL_write( ssl, 0, 0 )
没有选择似乎没有阻塞,虽然我不确定是否正在做我需要做的事情...
答案 0 :(得分:0)
SSL_Pending用于预读,不是为了您正在使用的目的。在下次读取完成时,阻止读取将自动重新协商。如果您使用的是ssl_set_fd,则可以在描述符上设置接收超时,在这种情况下它可能对您有所帮助。 How to set socket timeout in C when making multiple connections?
否则可以使用非阻塞io。