#include "StdAfx.h"
#include "SSLListener.h"
#include "ServerStartErrorException.h"
#include "TextTools.h"
#include "SSLClientConnection.h"

#define	CLASS_NAME	"SSLListener"


CSSLListener::CSSLListener(void)
{
	m_init = 0;
}

CSSLListener::~CSSLListener(void)
{
	Stop();
}


/*!
	開始
*/
void CSSLListener::Start(IServerToolIIPtr serverTool, IClientConnectionQueueIIPtr queue)
{
	//	初期化済み？
	if(m_init)
		return;
	m_init = TRUE;

	//	コピー
	m_serverTool = serverTool;
	m_queue = queue;
	m_setting = m_serverTool->GetManagerSetting(m_setting.GetSettingName());


	//	設定取得
	m_timeoutTime = m_setting.GetConnectionTimeoutTime();

	//	SSL初期化
	m_sslContext.Start(m_serverTool->GetIServerTool());

	//	リスナ初期化
	InitListenerBase(m_serverTool->GetIServerTool(), m_setting.GetListenErrorRetryTime());

	//	ポート追加
	AddPortsFromSetting(m_setting.GetPort());

	//	ポート数確認
	if(GetPortCount() == 0)
		throw CServerStartErrorException(CLASS_NAME, "待ち受けポートがひとつも指定されていません");

	//	スレッド起動
	StartListenerBase();
}

/*!
	停止
*/
void CSSLListener::Stop()
{
	//	初期化チェック
	if(!m_init)
		return;
	m_init = FALSE;

	//	リスナ停止
	StopListenerBase();

	//	SSL停止
	m_sslContext.Stop();
}

/*!
	停止準備
*/
void CSSLListener::ShutdownListen()
{
	//	初期化チェック
	if(!m_init)
		return;

	//	リスナ停止
	StopListenerBase();
}

/////////////////////////////////////////////////////////////////////////////////////
//	オーバーロード
/////////////////////////////////////////////////////////////////////////////////////
/*!
	クラス名取得
*/
LPCTSTR CSSLListener::GetListenerClassName()
{
	return CLASS_NAME;
}

/*!
	接続追加
*/
void CSSLListener::OnNewConnection(SOCKET newSock)
{
	try
	{
		m_queue->AddNewConnection(IClientConnectionRet(new CSSLClientConnection(newSock, m_sslContext.GetCTX(), m_timeoutTime), TRUE));
	}
	catch(CMemoryException *e)
	{
		e->Delete();

		m_serverTool->WriteSystemLog(GetListenerClassName(), SERVER_STATUS_ERROR, "メモリ不足が発生しました、一時的に接続を拒否します");

		//	メモリ不足のため、サーバ一時停止
		ForceDisableNewConnection(30 * 1000);
	}
}
