bool IApplication::queryPrimaryProcessID(uint32 currentProcessID, uint32 &primaryProcessID) const { primaryProcessID = 0; uint32 lastProcessID = 0; bool fileOpened = false; try { String syncFilePath = ProcessData::getSyncFilePath(); boost::interprocess::file_mapping shared_file(syncFilePath.to_ascii().c_str(), boost::interprocess::read_write); fileOpened = true; boost::interprocess::mapped_region shared_region(shared_file, boost::interprocess::read_write); if(shared_region.get_size() != sizeof(ProcessData)) { OS_LOG_ERROR("Process exception: corrupted file '" + syncFilePath + "'"); return false; } ProcessData *processData = static_cast<ProcessData *>(shared_region.get_address()); boost::interprocess::scoped_lock<boost::interprocess::interprocess_mutex> lock(processData->mutex, boost::posix_time::microsec_clock::universal_time() + boost::posix_time::millisec(OS_PROCESS_SHARED_MEMORY_LOCK_TIMEOUT)); if(!lock) { OS_LOG_ERROR(_S("Process exception: lock timeout")); return false; } lastProcessID = processData->processID; } catch(std::exception &e) { if(fileOpened) OS_LOG_DEBUG(_S("Process exception: ") + e.what()); return false; } shared_ptr<PlatformManager::ProcessDetails> lastProcessDetails = PlatformManager::instance()->getProcessDetails(lastProcessID); if(lastProcessDetails == nullptr) return false; // N.B.: non è sufficiente verificare se il processo è ancora attivo in quanto potrebbe essere terminato e il sistema operativo // abbia assegnato ad un nuovo processo l'ID appena letto, pertanto, se disponibile, bisogna verificare che i path degli eseguibili coincidano shared_ptr<PlatformManager::ProcessDetails> currentProcessDetails = PlatformManager::instance()->getProcessDetails(currentProcessID); OS_ASSERT(currentProcessDetails != nullptr); // I dettagli sul processo corrente dovrebbero essere sempre disponibili if(currentProcessDetails != nullptr) { // Verifica che sia stato possibile determinare il path degli eseguibili di entrambe i processi if((currentProcessDetails->executablePath.empty() == false) && (lastProcessDetails->executablePath.empty() == false)) { if(FileSystem::instance()->comparePaths(FileSystem::instance()->getFilePath(currentProcessDetails->executablePath), FileSystem::instance()->getFilePath(lastProcessDetails->executablePath)) == false) return false; } } primaryProcessID = lastProcessID; return true; }
bool IApplication::postPrimaryProcessCommand(uint32 primaryProcessID, std::string command) { if(command.empty()) { OS_ASSERTFALSE(); return false; } try { String syncFilePath = ProcessData::getSyncFilePath(); boost::interprocess::file_mapping shared_file(syncFilePath.to_ascii().c_str(), boost::interprocess::read_write); boost::interprocess::mapped_region shared_region(shared_file, boost::interprocess::read_write); if(shared_region.get_size() != sizeof(ProcessData)) { OS_LOG_ERROR("Process exception: corrupted file '" + syncFilePath + "'"); return false; } ProcessData *processData = static_cast<ProcessData *>(shared_region.get_address()); boost::interprocess::scoped_lock<boost::interprocess::interprocess_mutex> lock(processData->mutex, boost::posix_time::microsec_clock::universal_time() + boost::posix_time::millisec(OS_PROCESS_SHARED_MEMORY_LOCK_TIMEOUT)); if(!lock) { OS_LOG_ERROR(_S("Process exception: lock timeout")); return false; } String dataFilePath = processData->getDataFilePath(); shared_ptr<File> dataFile(OS_NEW File()); if(dataFile->open(dataFilePath, File::ofWrite | File::ofNoTruncate) == false) { OS_LOG_ERROR("Error opening or creating file '" + dataFilePath + "'"); return false; } if(dataFile->size() > 0) { dataFile->seekToEnd(); command.insert(0, OS_IAPPLICATION_COMMANDS_SEPARATOR); } if(dataFile->write(command.data(), static_cast<uint32>(command.size())) != static_cast<uint32>(command.size())) { OS_LOG_ERROR("Error writing file '" + dataFilePath + "'"); return false; } } catch(std::exception &e) { OS_LOG_DEBUG(_S("Process exception: ") + e.what()); return false; } return true; }
bool IApplication::peekProcessData(std::string &data) { data.clear(); try { String syncFilePath = ProcessData::getSyncFilePath(); boost::interprocess::file_mapping shared_file(syncFilePath.to_ascii().c_str(), boost::interprocess::read_write); boost::interprocess::mapped_region shared_region(shared_file, boost::interprocess::read_write); if(shared_region.get_size() != sizeof(ProcessData)) { OS_LOG_ERROR("Process exception: corrupted file '" + syncFilePath + "'"); return false; } ProcessData *processData = static_cast<ProcessData *>(shared_region.get_address()); boost::interprocess::scoped_lock<boost::interprocess::interprocess_mutex> lock(processData->mutex, boost::posix_time::microsec_clock::universal_time() + boost::posix_time::millisec(OS_PROCESS_SHARED_MEMORY_LOCK_TIMEOUT)); if(!lock) { OS_LOG_ERROR(_S("Process exception: lock timeout")); return false; } String dataFilePath = processData->getDataFilePath(); Buffer dataFileBuffer; if(dataFileBuffer.load(dataFilePath) == false) return false; if(FileSystem::instance()->remove(dataFilePath) == false) { OS_LOG_ERROR("Cannot remove file '" + dataFilePath + "'"); return false; } data.assign(reinterpret_cast<const char *>(dataFileBuffer.getData()), dataFileBuffer.getSize()); } catch(std::exception &e) { OS_LOG_DEBUG(_S("Process exception: ") + e.what()); return false; } return data.empty() == false; }
void IApplication::cleanupProcess() { OS_ASSERT(isPrimaryProcess()); if(m_notifyListener != nullptr) { OS_ASSERT(m_notifyListener->running() == false); m_notifyListener.reset(); } try { String syncFilePath = ProcessData::getSyncFilePath(); { boost::interprocess::file_mapping shared_file(syncFilePath.to_ascii().c_str(), boost::interprocess::read_write); boost::interprocess::mapped_region shared_region(shared_file, boost::interprocess::read_write, 0, sizeof(ProcessData)); ProcessData *processData = OS_PLACEMENT_NEW(shared_region.get_address(), ProcessData); boost::interprocess::scoped_lock<boost::interprocess::interprocess_mutex> lock(processData->mutex, boost::posix_time::microsec_clock::universal_time() + boost::posix_time::millisec(OS_PROCESS_SHARED_MEMORY_LOCK_TIMEOUT)); if(lock) { String dataFilePath = ProcessData::getDataFilePath(m_processID); if(FileSystem::instance()->remove(dataFilePath) == false) OS_LOG_ERROR("Error removing file '" + dataFilePath + "'"); } else { OS_LOG_ERROR("Process exception: lock timeout"); } } if(isPrimaryProcess()) { if(boost::interprocess::file_mapping::remove(syncFilePath.to_ascii().c_str()) == false) OS_LOG_ERROR("Process exception: error removing file '" + syncFilePath + "'"); } } catch(std::exception &e) { OS_LOG_DEBUG(_S("Process exception: ") + e.what()); } }
bool IRCSession::handleResponse(const std::string &command) { IRCParser parser; shared_ptr<IIRCCommand> response = parser.parse(get_this_ptr(), command); if(response != nullptr) { processResponse(response); notifyCommand(response); shared_ptr<IIRCCommand> reply = response->getReply(); if(reply != nullptr) addRequest(reply, false); } else { OS_LOG_DEBUG(_S("Unknown IRC command '") + command + _S("'")); } return parser.getAlive(); }
void onHouseKeepingTimer(const boost::system::error_code& e) { static int iteration = 0; // // This will fire every hour. We will simply restart the timer // so io_serice thread does not exit. If the operation is aborted // it would mean the io service has been terminated. // if (e != boost::asio::error::operation_aborted) { { mutex_lock lock(_queueMutex); OsTimer::Time now = OsTimer::now(); OsTimer::Interval skew = now - _lastTick - (TIMER_SERVICE_TICK * TIMER_TIME_UNIT); _lastTick = now; if (iteration++ >= 10) { if (skew < TIMER_TIME_UNIT) { OS_LOG_DEBUG(FAC_KERNEL, "OsTimer::TimerService timer resolution: " << skew << " microseconds."); } else { OS_LOG_WARNING(FAC_KERNEL, "OsTimer::TimerService timer resolution: " << skew << " microseconds."); } iteration = 0; } // // Destroy timers that are queued back to us. // while (_timerQueue.size() > 0) _timerQueue.pop(); } _houseKeepingTimer.expires_from_now(boost::posix_time::seconds(TIMER_SERVICE_TICK)); _houseKeepingTimer.async_wait(boost::bind(&TimerService::onHouseKeepingTimer, this, boost::asio::placeholders::error)); } }
bool IApplication::registerAsPrimaryProcess() { OS_ASSERT(m_processID != 0); OS_ASSERT(isPrimaryProcess()); try { Buffer buffer; buffer.reserve(sizeof(ProcessData)); ProcessData *processData = OS_PLACEMENT_NEW(buffer.getData(), ProcessData); processData->processID = m_processID; if(buffer.save(ProcessData::getSyncFilePath()) == false) return false; } catch(std::exception &e) { OS_LOG_DEBUG(_S("Process exception: ") + e.what()); return false; } return true; }
void StateQueuePublisher::internal_run() { zmq::context_t context(1); zmq::socket_t socket(context, ZMQ_PUB); try { socket.bind(_zmqBindAddress.c_str()); } catch(zmq::error_t& error_) { return; } OS_LOG_NOTICE(FAC_NET, "StateQueuePublisher::internal_run() " << "Started accepting subscriptions at " << _zmqBindAddress); while(!_terminate) { StateQueueRecord record; if (_queue.dequeue(record)) { // // exit // if (_terminate) break; // // publish // std::string eventId = record.id; if (!record.watcherData && eventId.size() < 7) { OS_LOG_ERROR(FAC_NET, "StateQueuePublisher::publish eventId is too short - " << eventId); continue; } try { s_sendmore(socket, eventId); std::string data; if (!record.watcherData) { for (std::vector<std::string>::const_iterator iter = record.exclude.begin(); iter != record.exclude.end(); iter++) { data += *iter; data += " "; } if (data.empty()) data = "initial_data"; OS_LOG_DEBUG(FAC_NET, "StateQueuePublisher::publish " << " message-id: " << eventId << " exclude-app-id: " << data); } else { data = record.data; } // // Send the address // s_sendmore(socket, _zmqBindAddress); // // Send the data vector // s_sendmore(socket, data); // // Send the number of subscribers // std::string ev = eventId.substr(0, 7); int count = countSubscribers(ev); std::string strcount = boost::lexical_cast<std::string>(count); s_send(socket, strcount); OS_LOG_DEBUG(FAC_NET, "StateQueuePublisher::publish ZeroMQ send: " << eventId << ":" << data); if (!record.watcherData && !count) { OS_LOG_WARNING(FAC_NET, "StateQueuePublisher::publish " << "ZERO subscribers to handle message-id: " << eventId); } } catch(zmq::error_t& error_) { OS_LOG_WARNING(FAC_NET, "StateQueuePublisher::publish " << "ZMQ Error sending publish " << eventId << " Error: " << error_.what()); } } else { OS_LOG_ERROR(FAC_NET, "FAILED TO DEQUEUE!"); } } OS_LOG_NOTICE(FAC_NET, "StateQueuePublisher::internal_run() TERMINATED."); }
RedirectPlugin::LookUpStatus SipRedirectorAliasDB::lookUp( const SipMessage& message, UtlString& requestString, Url& requestUri, const UtlString& method, ContactList& contactList, RequestSeqNo requestSeqNo, int redirectorNo, SipRedirectorPrivateStorage*& privateStorage, ErrorDescriptor& errorDescriptor) { // If url param sipx-userforward = false, do not redirect to user-forward // aliases. UtlString userforwardParam; requestUri.getUrlParameter("sipx-userforward", userforwardParam); bool disableForwarding = userforwardParam.compareTo("false", UtlString::ignoreCase) == 0; if (disableForwarding) { Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "%s::lookUp user forwarding disabled by parameter", mLogName.data()); } bool isDomainAlias = false; UtlString domain; UtlString hostAlias; requestUri.getHostAddress(domain); UtlBoolean isMyHostAlias = mpSipUserAgent->isMyHostAlias(requestUri); if (mpSipUserAgent && domain != _localDomain && isMyHostAlias) { isDomainAlias = true; hostAlias = domain; requestUri.setHostAddress(_localDomain); } UtlString requestIdentity; requestUri.getIdentity(requestIdentity); OS_LOG_DEBUG(FAC_SIP, mLogName.data() << "::lookUp identity: " << requestIdentity.data() << " domain: " << domain.data() << " local-domain: " << _localDomain.data() << " isHostAlias: " << isMyHostAlias); //ResultSet aliases; //AliasDB::getInstance()->getContacts(requestUri, aliases); //int numAliasContacts = aliases.getSize(); EntityDB::Aliases aliases; bool isUserIdentity = false; EntityDB* entityDb = SipRegistrar::getInstance(NULL)->getEntityDB(); entityDb->getAliasContacts(requestUri, aliases, isUserIdentity); int numAliasContacts = aliases.size(); if (numAliasContacts > 0) { Os::Logger::instance().log(FAC_SIP, PRI_DEBUG, "%s::lookUp " "got %d AliasDB contacts", mLogName.data(), numAliasContacts); // Check if the request identity is a real user/extension UtlString realm; UtlString authType; SipXauthIdentity authIdentity; authIdentity.setIdentity(requestIdentity); for (EntityDB::Aliases::iterator iter = aliases.begin(); iter != aliases.end(); iter++) { // If disableForwarding and the relation value is "userforward", // do not record this contact. if (!(disableForwarding && iter->relation == ALIASDB_RELATION_USERFORWARD)) { UtlString contact = iter->contact.c_str(); Url contactUri(contact); // if the request identity is a real user if (isUserIdentity) { // Encode AuthIdentity into the URI authIdentity.encodeUri(contactUri, message); } contactUri.setUrlParameter(SIP_SIPX_CALL_DEST_FIELD, "AL"); if (numAliasContacts == 1 && isDomainAlias && isUserIdentity) { UtlString userId; contactUri.getUserId(userId); requestUri.setUserId(userId.data()); requestUri.getUri(requestString); OS_LOG_NOTICE(FAC_SIP, "SipRedirectorAliasDB::lookUp normalized request-uri to " << requestString.data()); } else { // Add the contact. contactList.add( contactUri, *this ); } } } } else if (isDomainAlias) { // // No alias found. If this is was towards a domain alias, make sure to reset it back to // the old value prior to feeding it to the rest of the redirectors. // requestUri.setHostAddress(hostAlias); requestUri.getUri(requestString); } return RedirectPlugin::SUCCESS; }