【问题标题】:Why is OpenSSL causing a sigpipe @ SSL_connect?为什么 OpenSSL 会导致 sigpipe @ SSL_connect?
【发布时间】:2016-04-04 16:48:54
【问题描述】:
    int sfd = socket(AF_INET6, SOCK_STREAM, 0);
    if (sfd < 0) continue;
    struct timeval timeout;
    timeout.tv_sec = 60;
    timeout.tv_usec = 0;
    setsockopt(sfd, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout, sizeof(timeout));
    setsockopt(sfd, SOL_SOCKET, SO_SNDTIMEO, (char *) &timeout, sizeof(timeout));
    if (connect(sfd, (struct sockaddr*) &ig, sizeof(struct sockaddr_in6))) {
        close(sfd);
        continue;
    }
    SSL* ssl = SSL_new(ctx);
    if (ssl == NULL) {
        close(sfd);
        continue;
    }
    SSL_set_connect_state(ssl);
    SSL_set_fd(ssl, sfd);
    printf("%i\n", SSL_get_fd(ssl));
    int con = SSL_connect(ssl);

OpenSSL 会在我调用 SSL_connect 的线路上触发 SIGPIPE。我运行了 GDB 并确保套接字没有关闭。在 /proc/fd/# 中,套接字在之前或之后都没有显示为关闭。我尝试切换 set_fd 和 connect_state 调用的顺序。我想我把 OpenSSL 搞砸了,但我似乎无法弄清楚。

【问题讨论】:

  • 在我为执行类似您的示例而编写的 C 代码中,我不需要显式调用 SSL_set_connect_state(ssl);你为什么用它?如果删除它会发生什么?
  • @Castaglia 没有任何变化。
  • 我想接下来要尝试的是安装一个虚拟/存根 SIGPIPE 信号处理程序。并验证服务器端的日志/信息,看看它是否拒绝任何东西。

标签: c linux openssl signals sigpipe


【解决方案1】:

如果应用程序写入连接的远程端已关闭的套接字,则内核会触发 SIGPIPE。请注意,在这种情况下,本地文件描述符仍然有效,但对其进行写入将导致 SIGPIPE 或 EPIPE 发出无法将数据传递到远程端的信号。

由于 SSL_connect 正在进行 SSL 握手,其中包含多个数据交换。我的猜测是服务器或中间的某个中间件(如防火墙)在握手完成之前关闭了连接。可以通过数据包捕获(即,wireshark 或类似工具)找到此行为的确切细节。

【讨论】:

    猜你喜欢
    • 2023-01-15
    • 1970-01-01
    • 2023-03-15
    • 2016-01-30
    • 1970-01-01
    • 2011-04-12
    • 2013-02-25
    • 2012-12-31
    • 2014-01-01
    相关资源
    最近更新 更多