2016-04-04 10 views
0
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で何かを混乱させたと思っていますが、わかりません。なぜOpenSSLはsigpipe @ SSL_connectを引き起こしていますか?

+0

あなたの例のように書いたCコードでは、 'SSL_set_connect_state(ssl)'への明示的な呼び出しは必要ありませんでした。なぜあなたはそれを使用していますか?それを削除するとどうなりますか? – Castaglia

+0

@Castaglia何も変わりません。 – JavaProphet

+0

次に試してみたいのは、ダミー/スタブSIGPIPEシグナルハンドラをインストールすることです。サーバー側のログ/情報を確認して、何かを拒否しているかどうかを確認します。 – Castaglia

答えて

0

SIGPIPEは、アプリケーションが接続のリモート側が閉じられたソケットに書き込みを行うと、カーネルによってトリガーされます。この場合、ローカルファイル記述子は依然として有効ですが、書き込みを行うとSIGPIPEまたはEPIPEはデータをリモートエンドに配信できないことを通知します。

SSL_connectはいくつかのデータ交換からなるSSLハンドシェイクを行っているためです。私の推測では、サーバーまたはいくつかの中間ボックス(ファイアウォールのような)は、ハンドシェイクが完了する前に接続を閉じていたということです。この挙動の正確な詳細は、パケットキャプチャ(すなわち、wiresharkまたはそれに類するもの)によって発見されるかもしれない。

関連する問題