■ 技術情報(開発メモ) ■


■OpenSSLと格闘する・スタティックライブラリ編 (2004/02/13)

サーバにDLLはあまり使いたくなかったので、OpenSSLをスタティックライブラリとして組み込もうと考た。
インストール方法を見ると、makeファイルを変えるだけで良い模様。
で、NMakeを実行し、問題なくライブラリが出来る。

早速組み込んでみる。
Debugでコンパイル後、リンクでライブラリ競合の警告が出るが、まあ、動く模様。
しかし、Releaseでコンパイルすると・・・リンクエラーの嵐

どうやら、ライブラリの使っているランタイムライブラリと、実行ファイルの使っているランタイムライブラリが違うのが原因のようだ。
VC++には、以下の3(6)種類のランタイムライブラリがある。

で、OpenSSLは標準で/MDオプションでコンパイルされるため、04鯖のRelease(/MTオプション)と組み合わせると、リンクエラーになる模様。
OpenSSLを各オプションでコンパイルし直し、6種類のライブラリを使い分ける事で、問題は解決した。
しかし、昔全く同じ事で引っかかったような・・・

■OpenSSLと格闘する・マルチスレッド編 (2004/02/13)

OpenSSLをマルチスレッドで利用するためには、二つのコールバック関数を登録する必要がある、と、FAQにあります。
要するに、排他処理を行うためのミューテックスを提供してやる必要があるわけですね。

OpenSSLのマニュアルは結構不親切ですが、マルチスレッドはテストコードがOpenSSLのソースにありますので、貰って来れば、まあ、さほど悩まなくとも実現できます。
FAQには二つとありますが、Win32環境では、ロック関数の登録のみで、スレッドID取得関数は必要ないようです。

・適当なサンプルコード(04鯖からコピペ)

HANDLE	*g_lock_cs = NULL;

void CSSLContext::InitLock()
{
	if(g_lock_cs == NULL)
	{
		int i;

		g_lock_cs=(HANDLE*)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(HANDLE));
		for (i=0; i<CRYPTO_num_locks(); i++)
			g_lock_cs[i]=CreateMutex(NULL,FALSE,NULL);

		CRYPTO_set_locking_callback(Locking_cb);
	}
}

void  CSSLContext::Locking_cb(int mode, int type,const char *file, int line)
{
	if (mode & CRYPTO_LOCK)
		WaitForSingleObject(g_lock_cs[type],INFINITE);
	else
		ReleaseMutex(g_lock_cs[type]);
}
				

しかし、コードがあるんなら、標準でサポートしてくれてもいいような・・・

■OpenSSLと格闘する・メモリリーク編 (2004/02/13)

OpenSSLとは、各種暗号化ツールを詰め合わせたライブラリです。
04WebServerではSSLの実装に使われています。

OpenSSLを使って一番初めに詰まったのが、メモリリーク
サンプルコードが、書籍やらネットやらに結構上がっているのですが、どれも漏れまくりです。
で、色々調べまわって見た結果、以下の事が分かりました。

・ライブラリ開放時、以下のコードを全て実行する必要がある

全て実行しないとリークするようです。
何を実行する必要があるか、どこかにまとめておいて欲しかったなあ・・・

・スレッドの終了時、ERR_remove_state(0) を実行する必要がある

これをしないと、スレッドが終了するたびにメモリリークを起こします。

とりあえず、ERR_remove_state(0) は忘れがちになるんで、注意が必要です。
しかし、書籍のサンプルコードがメモリリークしまくりなのは・・・まあ、本自体は良い本でしたが。