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

时间:2013-08-16 13:28:03

标签: 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层说明如果需要的话,可以像那样进行重新协商,如果有的话,还可以读取数据记录。 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 )没有选择似乎没有阻塞,虽然我不确定是否正在做我需要做的事情...

1 个答案:

答案 0 :(得分:0)

SSL_Pending用于预读,不是为了您正在使用的目的。在下次读取完成时,阻止读取将自动重新协商。如果您使用的是ssl_set_fd,则可以在描述符上设置接收超时,在这种情况下它可能对您有所帮助。 How to set socket timeout in C when making multiple connections?

否则可以使用非阻塞io。