ソケットを 10 年間使用しているマルチスレッド ネットワーク アプリケーションがあり、現在、OpenSSL 0.9.8L でアプリケーションを保護しようとしています。何年にもわたって、アプリケーションのネットワーク プロトコルは、単一ソケット接続の二重の性質を利用するように設計されてきました。アプリケーションは、同じソケットで同時に読み取りと書き込みを行います。アプリケーションは、基盤となるソケット自体を管理し、ソケット記述子を SSL_set_fd 経由で OpenSSL に渡します。
マルチスレッド サポート用に OpenSSL を構成し、CRYPTO_set_id_callback()、CRYPTO_set_locking_callback() などの静的ロック コールバックと動的ロック コールバックの両方を設定しました。ほとんどの場合、アプリケーションは正常に機能しますが、いくつかの異常が見られます。原因を特定するには、いくつかの質問に対する明確な回答が役立ちます。
OpenSSL のよくある質問のページには、OpenSSL はスレッド セーフであると記載されていますが、単一の「SSL 接続は複数のスレッドで同時に使用されない可能性がある」と記載されています。
http://www.openssl.org/support/faq.html#PROG1
- 正しいか間違っているか。OpenSSL 接続 API 呼び出し (SSL_Read、SSL_Write など) は、同じ SSL インスタンス (SSL_new 呼び出しによって返される SSL へのポインター) で同時に実行できますか?
- 正しいか間違っているか。SSL_MODE_AUTO_RETRY が有効になっているソケットをブロックするために、スレッド A は SSL インスタンス X で SSL_Read() を呼び出し、同時にスレッド B は SSL インスタンス X で SSL_Write() を呼び出すことができますか?
- 正しいか間違っているか。アプリケーションがノンブロッキング ソケットを使用し、同じ SSL インスタンスでの SSL_Read と SSL_Write (および他の接続 API 呼び出し) の同時実行を防止する場合、OpenSSL はエラーなしで動作しますか?
- 正しいか間違っているか。SSL_new によって返された OpenSSL SSL インスタンスは、SSL_new を呼び出した単一のスレッドにバインドされます。バインドされていることは、SSL インスタンスが他のスレッドと共有されない可能性があることを意味します。SSL インスタンスは、SSL_new を呼び出したスレッドでの使用に対してのみ有効です?
- 正しいか間違っているか。スレッド A が i) SSL_new を呼び出し、SSL インスタンス X を取得し、ii) SSL インスタンス X を使用して SSL_Read を呼び出す場合、スレッド B が同じ SSL インスタンス X を使用して SSL_Read/SSL_Write を非同時に呼び出すと、最終的にエラーが発生します。