//---------------------------------------------------------------------------- // // 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 #include #include #include #include //#include "ace/Reactor.h" #include #include #include #include #include #include #include #include //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; }