SSL_read因SSL_ERROR_WANT_READ阻塞后必须要等SSL_read完成才可以继续调用SSL_write吗?

发布于 2022-09-02 23:32:30 字数 2213 浏览 16 评论 0

我现在项目需要将SSL阻塞方式改为非阻塞方式,使用的多线程,在一个线程中对一个SSL对象SSL_write,在另一个线程中使用该对象进行SSL_read操作。

《Network Security with OpenSSL》讲non-blocking的一节中有个data_transfer的示例程序:

for (;;)
{
    /* check_availability使用I/O复用接口(select、poll、epoll等)来获取socket是否可读或可写 */
    check_availability(A, &can_read_A, &can_write_A, B, &can_read_B, &can_write_B);

    /* write_waiton_read_A:调用SSL_write时因SSL_ERROR_WANT_READ阻塞
     * write_waiton_write_A:调用SSL_write时因SSL_ERROR_WANT_WRITE阻塞
     * read_waiton_write_A:调用SSL_read时因SSL_ERROR_WANT_WRITE阻塞
     * read_waiton_read_A:调用SSL_read时因SSL_ERROR_WANT_READ阻塞
     */
     
    if (!(write_waiton_read_A || write_waiton_write_A) && // A的write没有完成
            (A2B_len != BUF_SIZE) &&
            /* A可读,或者之前read因WANT_WRITE阻塞而此时A可写 */
            (can_read_A || (can_write_A && read_waiton_write_A)))
    {
        read_waiton_read_A = 0;
        read_waiton_write_A = 0;

        code = SSL_read(A, A2B + A2B_len, BUF_SIZE - A2B_len);
        switch (SSL_get_error(A, code))
        {
            ...
        case SSL_ERROR_WANT_READ:
            read_waiton_read_A = 1;
            break;
            
         case SSL_ERROR_WANT_WRITE:
             read_waiton_write_A = 1;
             break;
            ...
        }
    }
    
    ...

    if (!(read_waiton_write_A || read_waiton_read_A) &&
        have_data_B2A &&
        /* A可写,或者write因WANT_READ阻塞而此时A可读 */
        (can_write_A || (can_read_A && write_waiton_read_A)))
    {
        write_waiton_read_A = 0;
        write_waiton_write_A = 0;

        code = SSL_write(A, B2A, B2A_len);
        switch (SSL_get_error(A, code))
        {
            ...
        case SSL_ERROR_WANT_READ:
            write_waiton_read_A = 1;
            break;
            
        case SSL_ERROR_WANT_WRITE:
            write_waiton_write_A = 1;
            ...
        }
    }

    ...
}

上面的代码中,如果A之前的SSL_read因SSL_ERROR_WANT_READ未完成,则需等SSL_read完成才能对A进行SSL_write(就算A此时可写)。

我程序中的连接在发送时同时需要接收,请问如果一个SSL对象的操作(比如SSL_read)阻塞(比如因SSL_ERROR_WANT_READ)后,必须等该操作完成后才能调用另外一个对应的操作(比如SSL_write)吗?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

三生殊途 2022-09-09 23:32:30

应该是的,由于重协商的存在,SSL_write也会产生SSL_ERROR_WANT_READ。如果你不处理完SSL_read,后面发生可读事件时,怎么知道要调用SSL_write还是SSL_read?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文