Why is OpenSSL causing a sigpipe @ SSL_connect?

时间:2016-04-04 16:48:54

标签: c linux openssl signals sigpipe

    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 causes a SIGPIPE to be fired on the line that I call SSL_connect on. I ran through with GDB and ensured that the socket is not closed. In /proc/fd/#, the socket does not appear closed before or after. I tried switching the order of my set_fd and connect_state calls. I imagine I messed something up with OpenSSL, but I cannot seem to figure it out.

1 个答案:

答案 0 :(得分:1)

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

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