21

openssl を使用して tls を実装しました。一部のデータを受信した後、サーバーから大きなデータをダウンロード中にSSL_ERROR_SYSCALLエラーが発生しました。小さいファイルの場合、このエラーは発生せず、エラーなしでダウンロードできます。ERR_get_error() は、大きなファイルに対してゼロを示しています。

Linux および C++ フレームワークを使用しています。失敗の理由を見つけるには?失敗の原因は何ですか?ご提案をよろしくお願いします。

4

6 に答える 6

13

SSL_ERROR_SYSCALLは、基盤となるI / O(この場合はTCPである必要があります)で問題が発生したことを示します。だから、あなたはerrnoでチェックしてみることができます。

OpenSSLヘルプによると:

SSL_ERROR_SYSCALL

I/Oエラーが発生しました。OpenSSLエラーキューには、エラーに関する詳細情報が含まれている場合があります。エラーキューが空の場合(つまり、ERR_get_error()が0を返す場合)、retを使用してエラーの詳細を調べることができます。ret== 0の場合、プロトコルに違反するEOFが観察されました。ret == -1の場合、基礎となるBIOはI / Oエラーを報告しました(UnixシステムのソケットI / Oについては、errnoで詳細を確認してください)。

于 2012-12-03T15:49:00.837 に答える
5

ソースコードを調べると、正確に何が起こったのかわからないときにSSL_get_error()返されることがわかります。SSL_ERROR_SYSCALL基本的に、「不明」の場合のデフォルトの戻りコードです。

たとえば、私の場合 (BIO でノンブロッキング IO を実行している場合):

int buf;
const int n = SSL_read(ssl, &buf, 0);
const int err = SSL_get_error(ssl, n);
const int st = ERR_get_error();

nが 0 の場合は、ただの理由errになります。SSL_ERROR_SYSCALLただしst、実際のエラーがなかったことを示す 0 のままです。SSL_readに 0 バイトが書き込まれたため、0 が返されましたbuf

errnoただし、詳細については、呼び出し後に/の値を探してWSAGetLastError()ください。

于 2015-02-24T20:16:46.447 に答える
4

バッファ サイズ 0 で SSL_read() を呼び出しているかどうかを確認します。SSL_pending() を使用して次のような間違いを犯しました。

int waitForReadFd = nBuf < bufSize;

if (waitForReadFd)
    FD_SET(fd, &rfds);

// ...
// select

int doReadFd = FD_ISSET(fd, &rfds) || SSL_pending(ssl);

if (doReadFd)
    n = SSL_read(ssl, buf, bufSize - nBuf);

バッファnBuf == bufSizeサイズ 0 で SSL_read() が呼び出されると、errno == 0 で SSL_ERROR_SYSCALL が発生します。

doReadFd チェックを変更すると、この問題を回避できます。

int doReadFd = FD_ISSET(fd, &rfds) || nBuf < bufSize && SSL_pending(ssl);
于 2015-05-04T09:35:51.653 に答える
0

Go アプリケーションでこのエラーが発生しました。Goから基礎となるopensslライブラリに接続するために、サードパーティのライブラリを使用していました。データの読み取り中に、サード パーティ ライブラリは、読み取るバッファー/データの長さを 32 ビットの C.int に変換していました。2GB 以上の大きなデータの場合、オーバーフローが発生し、負の値が C.SSL_read 関数に渡されます。その場合、SSL_ERROR_SYSCALL エラーが発生しました。

于 2020-07-10T11:10:09.807 に答える