283 lines
8.4 KiB
C++
283 lines
8.4 KiB
C++
//----------------------------------------------------------------------------
|
|
//
|
|
// Copyright (C) Intel Corporation, 2006 - 2007.
|
|
//
|
|
// File: mps.cpp
|
|
//
|
|
// Contents: The program's entry point, starting acceptors and connectors,
|
|
// timers, and the reactor to start accepting connections.
|
|
//
|
|
// Notes:
|
|
//----------------------------------------------------------------------------
|
|
|
|
//===================================================
|
|
// INCLUDES
|
|
//===================================================
|
|
#include <fstream>
|
|
|
|
#include <ace/Signal.h>
|
|
#include <ace/Logging_Strategy.h>
|
|
#include <ace/Get_Opt.h>
|
|
#include <ace/OS_NS_sys_stat.h>
|
|
//#include "ace/Reactor.h"
|
|
#include <ace/OS_NS_signal.h>
|
|
#include <ace/OS_NS_string.h>
|
|
#include <ace/OS_NS_unistd.h>
|
|
#include <ace/Synch_Traits.h>
|
|
#include <ace/Thread_Semaphore.h>
|
|
#include <ace/String_Base.h>
|
|
#include <ace/Auto_Ptr.h>
|
|
#include <ace/TP_Reactor.h>
|
|
|
|
//mps includes:
|
|
#include "DynamicConfiguration.h"
|
|
#include "acceptor.h"
|
|
#include "DevicePresence.h"
|
|
#include "MPSReactorTask.h"
|
|
#include "SocksSvcHandler.h"
|
|
#include "TunnelHandler.h"
|
|
#include "global.h"
|
|
#include "OptionsUtils.h"
|
|
#include "Logger.h"
|
|
#include "MPS_Class.h"
|
|
#include "GuardedCounter.h"
|
|
#include "Options.h"
|
|
|
|
//#define ACE_NTRACE 0
|
|
#define SLEEP_TIME 500
|
|
#define HEADING "Intel(R) Management Presence Server"
|
|
|
|
GuardedCounter TUNNEL_COUNTER;
|
|
GuardedCounter TCP_COUNTER;
|
|
STATUS validateLogFilePath(const ACE_TString& filePath, bool& absPath);
|
|
|
|
//===================================================
|
|
// Globals
|
|
//===================================================
|
|
ACE_Event stop_event;
|
|
|
|
//===================================================
|
|
// Initialize acceptors, logger, and reactor
|
|
//===================================================
|
|
/*int mps_init (int argc, ACE_TCHAR *argv[])
|
|
{
|
|
int status = 0;
|
|
dynamic_config.attach(&logger);
|
|
return status;
|
|
}*/
|
|
//===================================================
|
|
// Main
|
|
//===================================================
|
|
int run_main (int argc, ACE_TCHAR *argv[])
|
|
{
|
|
TUNNEL_COUNTER.SetMaxValue(MAX_TUNNEL_COUNTER);
|
|
TCP_COUNTER.SetMaxValue(MAX_TCP_COUNTER);
|
|
stop_event.reset();
|
|
int status = 0;
|
|
// Prepare the logging mechanism
|
|
logFileNameFull = "";
|
|
|
|
const ACE_TString* filePathPtr = getLogFilePath();
|
|
if (filePathPtr == NULL) {
|
|
ACE_ERROR_RETURN((MY_ERROR
|
|
ACE_TEXT("Failed getting log file name.\n")), -1);
|
|
}
|
|
ACE_TString filePath = *filePathPtr;
|
|
|
|
bool absPath;
|
|
if (validateLogFilePath(filePath, absPath) != STATUS_SUCCESS)
|
|
{
|
|
ACE_ERROR_RETURN((MY_ERROR ACE_TEXT ("Log file path is incorrect %s.\n"),
|
|
filePath.c_str()), -1);
|
|
}
|
|
if (!absPath)
|
|
{
|
|
logFileNameFull += absolutePath;
|
|
}
|
|
logFileNameFull += filePath;
|
|
|
|
// Create the appropriate directory
|
|
// Note: (not checking for return value, on failure, will find out later).
|
|
ACE_OS::mkdir(logFileNameFull.c_str());
|
|
|
|
// We must open the output file first.
|
|
const ACE_TString* logFileNamePtr = getLogFileName();
|
|
if (logFileNamePtr == NULL) {
|
|
ACE_ERROR_RETURN((MY_ERROR
|
|
ACE_TEXT("Failed getting output file name.\n")), -1);
|
|
}
|
|
const ACE_TString& logFileName = *logFileNamePtr;
|
|
logFileNameFull += logFileName;
|
|
|
|
ofstream log_file;
|
|
log_file.open(logFileNameFull.c_str(), ios::app | ios::out);
|
|
if (log_file.fail())
|
|
{
|
|
ACE_ERROR_RETURN((MY_ERROR
|
|
ACE_TEXT ("Failed opening log file for read/write.\n")), -1);
|
|
}
|
|
ACE_LOG_MSG->msg_ostream(&log_file);
|
|
ACE_LOG_MSG->open("MPS", ACE_Log_Msg::OSTREAM);
|
|
|
|
DynamicConfiguration dynamic_config;
|
|
MPS_Reactor_Task reactor_task;
|
|
Logger logger;
|
|
|
|
dynamic_config.attach(&logger);
|
|
|
|
|
|
ACE_Time_Value delay(DYNAMIC_CONFIGURATION_DELAY);
|
|
|
|
#if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_SERVICES) && defined (_SERVICE)
|
|
m_pLogger.LogInfoEvent(MPS_INFO, MPS_START);
|
|
#endif /* ACE_WIN32 && !(ACE_LACKS_WIN32_SERVICES) && (_SERVICE)*/
|
|
|
|
const unsigned int* nthreadsPtr = getThreadNumber();
|
|
if (nthreadsPtr == NULL) {
|
|
ACE_ERROR_RETURN((MY_ERROR
|
|
ACE_TEXT("Failed to get thread number.\n")), -1);
|
|
}
|
|
const unsigned int& nthreads = *nthreadsPtr;
|
|
if (reactor_task.start(nthreads) == 0)
|
|
{
|
|
if (logger.init(logFileNameFull.c_str()) == STATUS_FAILURE)
|
|
{
|
|
ACE_ERROR ((MY_ERROR ACE_TEXT ("Failed to initialize logger\n")));
|
|
}
|
|
|
|
ACE_DEBUG((MY_INFO ACE_TEXT("%s %s\n"), HEADING, "has started"));
|
|
|
|
// Start dynamic configuration first
|
|
if (dynamic_config.start(ACE_Time_Value(0), delay) == STATUS_FAILURE)
|
|
{
|
|
ACE_ERROR ((MY_ERROR ACE_TEXT ("Failed to start dynamic configuration\n")));
|
|
}
|
|
|
|
DevicePresence::instance().start();
|
|
|
|
// ---- Start AMT acceptors ---
|
|
|
|
ACE_INET_Addr amt_acceptor_address;
|
|
if (getAMTListenINET(amt_acceptor_address) != STATUS_SUCCESS)
|
|
{
|
|
|
|
ACE_ERROR ((MY_ERROR ACE_TEXT ("Failed to listen on AMT listen address, exiting MPS\n")));
|
|
#if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_SERVICES) && defined (_SERVICE)
|
|
m_pLogger.LogErrorEvent(MPS_ERROR, MPS_AMT_ACCEPTOR_FAIL_MESSAGE);
|
|
#endif /* ACE_WIN32 && !(ACE_LACKS_WIN32_SERVICES) && (_SERVICE)*/
|
|
return -1;
|
|
}
|
|
|
|
ACE_TCHAR buffer1[MAXHOSTNAMELEN];
|
|
amt_acceptor_address.addr_to_string(buffer1, MAXHOSTNAMELEN);
|
|
ACE_DEBUG((MY_TRACE ACE_TEXT("amt binding addr: %s"), buffer1));
|
|
if (MPS_Class::instance()->_amt_acceptor.start(amt_acceptor_address) == -1)
|
|
{
|
|
ACE_TCHAR buffer[MAXHOSTNAMELEN];
|
|
if (amt_acceptor_address.addr_to_string(buffer, MAXHOSTNAMELEN) != -1)
|
|
{
|
|
ACE_ERROR ((MY_ERROR ACE_TEXT ("Failed to listen on %p, exiting MPS\n"),buffer));
|
|
}
|
|
#if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_SERVICES) && defined (_SERVICE)
|
|
m_pLogger.LogErrorEvent(MPS_ERROR, MPS_AMT_ACCEPTOR_FAIL_MESSAGE);
|
|
#endif /* ACE_WIN32 && !(ACE_LACKS_WIN32_SERVICES) && (_SERVICE)*/
|
|
return -1;
|
|
}
|
|
|
|
|
|
// ------- Start SOCKS acceptor --------
|
|
ACE_INET_Addr socks_acceptor_address;
|
|
if (getListenINET(NETWORK_SECTION, MC_SOCKS_LISTEN_IP_ELEMENT, MC_SOCKS_LISTEN_PORT_ELEMENT, socks_acceptor_address) != STATUS_SUCCESS)
|
|
{
|
|
ACE_ERROR ((MY_ERROR ACE_TEXT ("Failed to listen on Socks listen address, exiting MPS\n")));
|
|
#if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_SERVICES) && defined (_SERVICE)
|
|
m_pLogger.LogErrorEvent(MPS_ERROR, MPS_SOCKS_ACCEPTOR_FAIL_MESSAGE);
|
|
#endif /* ACE_WIN32 && !(ACE_LACKS_WIN32_SERVICES) && (_SERVICE)*/
|
|
return -1;
|
|
}
|
|
|
|
if (MPS_Class::instance()->_socks_acceptor.start(socks_acceptor_address) == -1)
|
|
{
|
|
ACE_TCHAR buffer[MAXHOSTNAMELEN];
|
|
if (socks_acceptor_address.addr_to_string(buffer, MAXHOSTNAMELEN) != -1)
|
|
{
|
|
ACE_ERROR ((MY_ERROR ACE_TEXT ("Failed to listen on %p, exiting MPS\n"),buffer));
|
|
}
|
|
#if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_SERVICES) && defined (_SERVICE)
|
|
m_pLogger.LogErrorEvent(MPS_ERROR, MPS_SOCKS_ACCEPTOR_FAIL_MESSAGE);
|
|
#endif /* ACE_WIN32 && !(ACE_LACKS_WIN32_SERVICES) && (_SERVICE)*/
|
|
return -1;
|
|
}
|
|
|
|
}
|
|
|
|
stop_event.wait();
|
|
|
|
delete(ConfigFormats::instance());
|
|
delete(Options::instance());
|
|
ACE_LOG_MSG->msg_ostream(&std::cerr, true);
|
|
|
|
#if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_SERVICES) && defined (_SERVICE)
|
|
Sleep(SLEEP_TIME);
|
|
ExitProcess(status);
|
|
#endif /* ACE_WIN32 && !(ACE_LACKS_WIN32_SERVICES) && (_SERVICE)*/
|
|
log_file.close();
|
|
return status;
|
|
}
|
|
|
|
#if defined (ACE_WIN32) && !defined (ACE_LACKS_WIN32_SERVICES) && defined (_SERVICE)
|
|
int closeMPS()
|
|
{
|
|
ACE_DEBUG((MY_INFO ACE_TEXT("---------< MPS Stopping >----------\n")));
|
|
|
|
// Close the acceptors (release the sockets)
|
|
MPS_Class::instance()->_socks_acceptor.close();
|
|
MPS_Class::instance()->_amt_acceptor.close();
|
|
ACE_Thread_Manager::instance ()->cancel_all();
|
|
Sleep(1000);
|
|
ACE_Thread_Manager::instance ()->suspend_all();
|
|
|
|
stop_event.signal();
|
|
return 0;
|
|
}
|
|
#endif /* ACE_WIN32 && !(ACE_LACKS_WIN32_SERVICES) && (_SERVICE)*/
|
|
|
|
// Used to validate the log file path given.
|
|
// Enters into absPath if the path is absolute or not
|
|
// Returns STATUS_SUCCESS if it is correct,
|
|
// returns STATUS_FAILURE otherwise.
|
|
STATUS validateLogFilePath(const ACE_TString& filePath, bool& absPath)
|
|
{
|
|
absPath = false;
|
|
|
|
// first check if it is an absolute or relative path
|
|
if (!filePath.empty() &&
|
|
((filePath[1] == ':') ||
|
|
((filePath[0] == '\\') && (filePath[1] == '\\'))))
|
|
{
|
|
absPath = true;
|
|
}
|
|
|
|
if (!absPath && filePath.empty())
|
|
{
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
if (filePath[0] == '\\')
|
|
{
|
|
return STATUS_FAILURE;
|
|
}
|
|
|
|
#ifdef ACE_WIN32
|
|
if ((filePath[filePath.length()-1] != '/') &&
|
|
(filePath[filePath.length()-1] != '\\'))
|
|
#else
|
|
if (filePath[filePath.length()-1] != '/')
|
|
#endif
|
|
{
|
|
return STATUS_FAILURE;
|
|
}
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|