// send a message to a module within another service asynchronously Boolean ModuleController::ModuleSendAsync(const pegasus_module & handle, Uint32 msg_handle, Uint32 destination_q, const String & destination_module, AsyncRequest *message, void *callback_parm) { if ( false == verify_handle(const_cast<pegasus_module *>(&handle))) throw(Permission(pegasus_thread_self())); AsyncOpNode *op = get_op(); AsyncModuleOperationStart *request = new AsyncModuleOperationStart(msg_handle, op, destination_q, getQueueId(), true, destination_module, message); request->dest = destination_q; callback_handle *cb = new callback_handle(const_cast<pegasus_module *>(&handle), callback_parm); return SendAsync(op, destination_q, _async_handleEnqueue, this, cb); }
// send an async message to a service asynchronously Boolean ModuleController::ModuleSendAsync(const pegasus_module & handle, Uint32 msg_handle, Uint32 destination_q, AsyncRequest *message, void *callback_parm) { //printf("verifying handle %p, controller at %p \n", &handle, this); if ( false == verify_handle(const_cast<pegasus_module *>(&handle))) throw(Permission(pegasus_thread_self())); if (message->op == NULL) { message->op = get_op(); message->op->put_request(message); } callback_handle *cb = new callback_handle(const_cast<pegasus_module *>(&handle), callback_parm); message->setRouting(msg_handle); message->resp = getQueueId(); message->block = false; message->dest = destination_q; return SendAsync(message->op, destination_q, _async_handleEnqueue, this, cb); }
AsyncReply *ModuleController::_send_wait(Uint32 destination_q, const String & destination_module, AsyncRequest *message) { AutoPtr<AsyncModuleOperationStart> request(new AsyncModuleOperationStart(get_next_xid(), 0, destination_q, getQueueId(), true, destination_module, message)); request->dest = destination_q; AutoPtr<AsyncModuleOperationResult> response(static_cast<AsyncModuleOperationResult *>(SendWait(request.get()))); AsyncReply *ret = 0; if (response.get() != NULL && response->getType() == async_messages::ASYNC_MODULE_OP_RESULT ) { ret = static_cast<AsyncReply *>(response->get_result()); //clear the request out of the envelope so it can be deleted by the module } request->get_action(); return ret; }
Boolean ModuleController::deregister_module(const String & module_name) { AutoPtr<DeRegisteredModule> request(new DeRegisteredModule(get_next_xid(), 0, true, getQueueId(), module_name)); request->dest = _meta_dispatcher->getQueueId(); AutoPtr<AsyncReply> response(SendWait(request.get())); request.reset(); response.reset(); pegasus_module *module; _module_lock lock(&_modules); module = _modules.next(0); while(module != NULL ) { if( module->get_name() == module_name) { _modules.remove_no_lock(module); return true; } module = _modules.next(module); } return false; }
Boolean ModuleController::_send_forget(Uint32 destination_q, const String & destination_module, AsyncRequest *message) { AsyncOpNode *op = get_op(); message->dest = destination_q; AsyncModuleOperationStart *request = new AsyncModuleOperationStart(0, op, destination_q, getQueueId(), true, destination_module, message); return SendForget(request); }
cimom::~cimom() { PEGASUS_ASSERT(_routed_queue_shutdown.get() == 0); AsyncIoClose *msg = new AsyncIoClose( 0, getQueueId()); msg->op = get_cached_op(); msg->op->_flags = ASYNC_OPFLAGS_FIRE_AND_FORGET; msg->op->_op_dest = _global_this; msg->op->_request.reset(msg); Boolean done = _routed_ops.enqueue(msg->op); PEGASUS_ASSERT(done); _routing_thread.join(); PEGASUS_ASSERT(_routed_queue_shutdown.get()); PEGASUS_ASSERT(_die.get()); }
/** _bind - creates a new server socket and bind socket to the port address. If PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET is not defined, the port number is ignored and a domain socket is bound. */ void HTTPAcceptor::_bind() { #ifdef PEGASUS_OS_PASE AutoPtr<PaseCcsid> ccsid; #endif PEGASUS_ASSERT(_rep != 0); // Create address: memset(_rep->address, 0, _rep->address_size); if (_connectionType == LOCAL_CONNECTION) { #ifndef PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET // // Make sure the local domain socket can be owned by the cimserver // user. Otherwise, the bind may fail with a vague "bind failed" // error. // #ifdef PEGASUS_OS_PASE // PASE domain socket needs ccsid 819 int orig_ccsid; orig_ccsid = _SETCCSID(-1); if (orig_ccsid == -1) { PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1, "HTTPAcceptor::_bind: Can not get current PASE CCSID."); orig_ccsid = 1208; } ccsid.reset(new PaseCcsid(819, orig_ccsid)); #endif if (System::exists(PEGASUS_LOCAL_DOMAIN_SOCKET_PATH)) { if (!System::removeFile(PEGASUS_LOCAL_DOMAIN_SOCKET_PATH)) { throw CannotRemoveFile(PEGASUS_LOCAL_DOMAIN_SOCKET_PATH); } } reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_family = AF_UNIX; strcpy(reinterpret_cast<struct sockaddr_un*>(_rep->address)->sun_path, PEGASUS_LOCAL_DOMAIN_SOCKET_PATH); #else PEGASUS_ASSERT(false); #endif } #ifdef PEGASUS_ENABLE_IPV6 else if (_connectionType == IPV6_CONNECTION) { reinterpret_cast<struct sockaddr_in6*>(_rep->address)->sin6_addr = in6addr_any; reinterpret_cast<struct sockaddr_in6*>(_rep->address)->sin6_family = AF_INET6; reinterpret_cast<struct sockaddr_in6*>(_rep->address)->sin6_port = htons(_portNumber); } #endif else if(_connectionType == IPV4_CONNECTION) { reinterpret_cast<struct sockaddr_in*>(_rep->address)->sin_addr.s_addr = INADDR_ANY; reinterpret_cast<struct sockaddr_in*>(_rep->address)->sin_family = AF_INET; reinterpret_cast<struct sockaddr_in*>(_rep->address)->sin_port = htons(_portNumber); } else { PEGASUS_ASSERT(false); } // Create socket: if (_connectionType == LOCAL_CONNECTION) { _rep->socket = Socket::createSocket(AF_UNIX, SOCK_STREAM, 0); } #ifdef PEGASUS_ENABLE_IPV6 else if (_connectionType == IPV6_CONNECTION) { _rep->socket = Socket::createSocket(PF_INET6, SOCK_STREAM, IPPROTO_TCP); } #endif else if (_connectionType == IPV4_CONNECTION) { _rep->socket = Socket::createSocket(PF_INET, SOCK_STREAM, IPPROTO_TCP); } else { PEGASUS_ASSERT(false); } if (_rep->socket < 0) { delete _rep; _rep = 0; MessageLoaderParms parms("Common.HTTPAcceptor.FAILED_CREATE_SOCKET", "Failed to create socket"); throw BindFailedException(parms); } Socket::disableBlocking(_rep->socket); // set the close-on-exec bit for this file handle. // any unix that forks needs this bit set. #if !defined PEGASUS_OS_TYPE_WINDOWS && !defined(PEGASUS_OS_VMS) int sock_flags; if ((sock_flags = fcntl(_rep->socket, F_GETFD, 0)) < 0) { PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1, "HTTPAcceptor::_bind: fcntl(F_GETFD) failed"); } else { sock_flags |= FD_CLOEXEC; if (fcntl(_rep->socket, F_SETFD, sock_flags) < 0) { PEG_TRACE_CSTRING(TRC_DISCARDED_DATA, Tracer::LEVEL1, "HTTPAcceptor::_bind: fcntl(F_SETFD) failed"); } } #endif // // Set the socket option SO_REUSEADDR to reuse the socket address so // that we can rebind to a new socket using the same address when we // need to resume the cimom as a result of a timeout during a Shutdown // operation. // int opt=1; if (setsockopt(_rep->socket, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) < 0) { delete _rep; _rep = 0; MessageLoaderParms parms("Common.HTTPAcceptor.FAILED_SET_SOCKET_OPTION", "Failed to set socket option"); throw BindFailedException(parms); } // // Bind socket to port: // if (::bind(_rep->socket, _rep->address, _rep->address_size) < 0) { MessageLoaderParms parms( "Common.HTTPAcceptor.FAILED_BIND_SOCKET_DETAIL", "Failed to bind socket on port $0: $1.", _portNumber, PEGASUS_SYSTEM_NETWORK_ERRORMSG_NLS); delete _rep; _rep = 0; throw BindFailedException(parms); } // // Get the actual port value used if the caller specified a port value of 0. // if (_portNumber == 0) { sockaddr_in buf; SocketLength bufSize = sizeof(buf); if (getsockname(_rep->socket, reinterpret_cast<sockaddr *>(&buf), &bufSize) == 0 ) { _portNumber = ntohs(buf.sin_port); } } // // Change permissions on Linux local domain socket to allow writes by // others. // #if !defined(PEGASUS_DISABLE_LOCAL_DOMAIN_SOCKET) && \ (defined(PEGASUS_PLATFORM_LINUX_GENERIC_GNU) || \ defined(PEGASUS_OS_ZOS) || \ defined(PEGASUS_OS_PASE)) if (_connectionType == LOCAL_CONNECTION) { if (::chmod(PEGASUS_LOCAL_DOMAIN_SOCKET_PATH, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH ) < 0 ) { MessageLoaderParms parms( "Common.HTTPAcceptor.FAILED_SET_LDS_FILE_OPTION", "Failed to set permission on local domain socket {0}: {1}.", PEGASUS_LOCAL_DOMAIN_SOCKET_PATH, PEGASUS_SYSTEM_ERRORMSG_NLS ); delete _rep; _rep = 0; throw BindFailedException(parms); } } #endif // Set up listening on the given socket: //int const _maxConnectionQueueLength = 15; if (::listen(_rep->socket, _maxConnectionQueueLength) < 0) { MessageLoaderParms parms( "Common.HTTPAcceptor.FAILED_LISTEN_SOCKET", "Failed to listen on socket {0}: {1}.", (int)_rep->socket,PEGASUS_SYSTEM_NETWORK_ERRORMSG_NLS ); delete _rep; _rep = 0; throw BindFailedException(parms); } // Register to receive SocketMessages on this socket: if (-1 == ( _entry_index = _monitor->solicitSocketMessages( _rep->socket, SocketMessage::READ | SocketMessage::EXCEPTION, getQueueId(), MonitorEntry::TYPE_ACCEPTOR))) { delete _rep; _rep = 0; MessageLoaderParms parms( "Common.HTTPAcceptor.FAILED_SOLICIT_SOCKET_MESSAGES", "Failed to solicit socket messaeges"); throw BindFailedException(parms); } }
void WsmProcessor::handleRequest(WsmRequest* wsmRequest) { PEG_METHOD_ENTER(TRC_WSMSERVER, "WsmProcessor::handleRequest()"); // Process requests by type. For now, only WS-Transfer operations are // implemented, and they all are handled by forwarding to the CIM Server. AutoPtr<WsmRequest> wsmRequestDestroyer(wsmRequest); try { CIMOperationRequestMessage* cimRequest = _wsmToCimRequestMapper.mapToCimRequest(wsmRequest); // Requests that do not have a CIM representation are mapped to NULL // and are meant to be handled by the WSM processor itself. if (cimRequest) { // Save the request until the response comes back. // Note that the CIM request has its own unique message ID. { AutoMutex am(_mutex); _requestTable.insert(cimRequest->messageId, wsmRequest); wsmRequestDestroyer.release(); } cimRequest->queueIds.push(getQueueId()); _cimOperationProcessorQueue->enqueue(cimRequest); } else { switch (wsmRequest->getType()) { case WS_ENUMERATION_PULL: _handlePullRequest((WsenPullRequest*) wsmRequest); break; case WS_ENUMERATION_RELEASE: _handleReleaseRequest((WsenReleaseRequest*) wsmRequest); break; default: break; } } } catch (WsmFault& fault) { sendResponse(new WsmFaultResponse(wsmRequest, fault)); } catch (CIMException& e) { sendResponse(new WsmFaultResponse( wsmRequest, _cimToWsmResponseMapper.mapCimExceptionToWsmFault(e))); } catch (Exception& e) { sendResponse(new WsmFaultResponse( wsmRequest, WsmFault( WsmFault::wsman_InternalError, e.getMessage(), e.getContentLanguages()))); } catch (PEGASUS_STD(exception)& e) { sendResponse(new WsmFaultResponse( wsmRequest, WsmFault(WsmFault::wsman_InternalError, e.what()))); } catch (...) { sendResponse(new WsmFaultResponse( wsmRequest, WsmFault(WsmFault::wsman_InternalError))); } // Note this requirement when Enumerate/Pull operations are supported: // DSP0226 R6.3-5: For operations that span multiple message sequences, // the wsman:Locale element is processed in the initial message only. // It should be ignored in subsequent messages because the first // message establishes the required locale. The service may issue a // fault if the wsman:Locale is present in subsequent messages and the // value is different from that used in the initiating request. PEG_METHOD_EXIT(); }
CIMHandleIndicationResponseMessage* IndicationHandlerService::_handleIndication( CIMHandleIndicationRequestMessage* request) { PEG_METHOD_ENTER (TRC_IND_HANDLE, "IndicationHandlerService::_handleIndication"); CIMException cimException = PEGASUS_CIM_EXCEPTION(CIM_ERR_SUCCESS, String::EMPTY); CIMName className = request->handlerInstance.getClassName(); CIMNamespaceName nameSpace = request->nameSpace; CIMInstance indication = request->indicationInstance; CIMInstance handler = request->handlerInstance; Uint32 pos = PEG_NOT_FOUND; if (className.equal (PEGASUS_CLASSNAME_INDHANDLER_CIMXML) || className.equal (PEGASUS_CLASSNAME_LSTNRDST_CIMXML)) { pos = handler.findProperty(PEGASUS_PROPERTYNAME_LSTNRDST_DESTINATION); if (pos == PEG_NOT_FOUND) { cimException = PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED, MessageLoaderParms("HandlerService.IndicationHandlerService." "CIMXML_HANDLER_WITHOUT_DESTINATION", "CIMXml Handler missing Destination property")); } else { CIMProperty prop = handler.getProperty(pos); String destination = prop.getValue().toString(); if (destination.size() == 0) { cimException = PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED, MessageLoaderParms("HandlerService.IndicationHandlerService." "INVALID_DESTINATION", "invalid destination")); } //compared index 10 is not : else if (destination.subString(0, 10) == String("localhost/")) { Array<Uint32> exportServer; find_services(PEGASUS_QUEUENAME_EXPORTREQDISPATCHER, 0, 0, &exportServer); // Listener is build with Cimom, so send message to ExportServer AutoPtr<CIMExportIndicationRequestMessage> exportmessage( new CIMExportIndicationRequestMessage( XmlWriter::getNextMessageId(), destination.subString(21), //taking localhost/CIMListener portion out from reg indication, QueueIdStack(exportServer[0], getQueueId()), String::EMPTY, String::EMPTY)); exportmessage->operationContext.set( request->operationContext.get( ContentLanguageListContainer::NAME)); AutoPtr<AsyncOpNode> op( this->get_op()); AutoPtr<AsyncLegacyOperationStart> asyncRequest( new AsyncLegacyOperationStart( get_next_xid(), op.get(), exportServer[0], exportmessage.get(), _queueId)); exportmessage.release(); PEG_TRACE_STRING(TRC_IND_HANDLE, Tracer::LEVEL4, "Indication handler forwarding message to " + ((MessageQueue::lookup(exportServer[0])) ? String( ((MessageQueue::lookup(exportServer[0]))-> getQueueName()) ) : String("BAD queue name"))); //SendAsync(op, // exportServer[0], // IndicationHandlerService::_handleIndicationCallBack, // this, // (void *)request->queueIds.top()); AutoPtr<AsyncReply> asyncReply(SendWait(asyncRequest.get())); asyncRequest.release(); // Return the ExportIndication results in HandleIndication //response AutoPtr<CIMExportIndicationResponseMessage> exportResponse( reinterpret_cast<CIMExportIndicationResponseMessage *>( (static_cast<AsyncLegacyOperationResult *>( asyncReply.get()))->get_result())); cimException = exportResponse->cimException; op->release(); this->return_op(op.release()); } else { _loadHandler(request, cimException); } } } else if (className.equal (PEGASUS_CLASSNAME_INDHANDLER_SNMP)) { pos = handler.findProperty(PEGASUS_PROPERTYNAME_LSTNRDST_TARGETHOST); if (pos == PEG_NOT_FOUND) { cimException = PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED, MessageLoaderParms("HandlerService.IndicationHandlerService." "SNMP_HANDLER_WITHOUT_TARGETHOST", "Snmp Handler missing Targethost property")); } else { CIMProperty prop = handler.getProperty(pos); String destination = prop.getValue().toString(); if (destination.size() == 0) { cimException = PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED, MessageLoaderParms("HandlerService.IndicationHandlerService." "INVALID_TARGETHOST", "invalid targethost")); } else { _loadHandler(request, cimException); } } } else if ((className.equal (PEGASUS_CLASSNAME_LSTNRDST_SYSTEM_LOG)) || (className.equal (PEGASUS_CLASSNAME_LSTNRDST_EMAIL))) { _loadHandler(request, cimException); } CIMHandleIndicationResponseMessage* response = new CIMHandleIndicationResponseMessage( request->messageId, cimException, request->queueIds.copyAndPop()); delete request; return response; }
CIMHandleIndicationResponseMessage* IndicationHandlerService::_handleIndication( CIMHandleIndicationRequestMessage* request) { PEG_METHOD_ENTER(TRC_IND_HANDLER, "IndicationHandlerService::_handleIndication()"); Boolean handleIndicationSuccess = true; CIMException cimException = PEGASUS_CIM_EXCEPTION(CIM_ERR_SUCCESS, String::EMPTY); CIMName className = request->handlerInstance.getClassName(); CIMNamespaceName nameSpace = request->nameSpace; CIMInstance indication = request->indicationInstance; CIMInstance handler = request->handlerInstance; PEG_TRACE ((TRC_INDICATION_GENERATION, Tracer::LEVEL4, "Handler service received %s Indication %s for %s:%s.%s Handler", (const char*)(indication.getClassName().getString().getCString()), (const char*)(request->messageId.getCString()), (const char*)(request->nameSpace.getString().getCString()), (const char*)(handler.getClassName().getString().getCString()), (const char*)(handler.getProperty(handler.findProperty( PEGASUS_PROPERTYNAME_NAME)).getValue().toString().getCString()))); Uint32 pos = PEG_NOT_FOUND; if (className.equal (PEGASUS_CLASSNAME_INDHANDLER_CIMXML) || className.equal (PEGASUS_CLASSNAME_LSTNRDST_CIMXML)) { pos = handler.findProperty(PEGASUS_PROPERTYNAME_LSTNRDST_DESTINATION); if (pos == PEG_NOT_FOUND) { cimException = PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED, MessageLoaderParms( "HandlerService.IndicationHandlerService." "CIMXML_HANDLER_WITHOUT_DESTINATION", "CIMXml Handler missing Destination property")); handleIndicationSuccess = false; } else { CIMProperty prop = handler.getProperty(pos); String destination = prop.getValue().toString(); if (destination.size() == 0) { cimException = PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED, MessageLoaderParms( "HandlerService.IndicationHandlerService." "INVALID_DESTINATION", "invalid destination")); handleIndicationSuccess = false; } //compared index 10 is not : else if (destination.subString(0, 10) == String("localhost/")) { Uint32 exportServer = find_service_qid(PEGASUS_QUEUENAME_EXPORTREQDISPATCHER); // Listener is build with Cimom, so send message to ExportServer AutoPtr<CIMExportIndicationRequestMessage> exportmessage( new CIMExportIndicationRequestMessage( XmlWriter::getNextMessageId(), //taking localhost/CIMListener portion out from reg destination.subString(21), indication, QueueIdStack(exportServer, getQueueId()), String::EMPTY, String::EMPTY)); exportmessage->operationContext.insert( IdentityContainer(String::EMPTY)); exportmessage->operationContext.set( request->operationContext.get( ContentLanguageListContainer::NAME)); AutoPtr<AsyncOpNode> op( this->get_op()); AutoPtr<AsyncLegacyOperationStart> asyncRequest( new AsyncLegacyOperationStart( op.get(), exportServer, exportmessage.get())); exportmessage.release(); PEG_TRACE((TRC_IND_HANDLER, Tracer::LEVEL4, "Indication handler forwarding message to %s", ((MessageQueue::lookup(exportServer)) ? ((MessageQueue::lookup(exportServer))-> getQueueName()): "BAD queue name"))); PEG_TRACE ((TRC_INDICATION_GENERATION, Tracer::LEVEL4, "Sending %s Indication %s to destination %s", (const char*) (indication.getClassName().getString(). getCString()), (const char*)(request->messageId.getCString()), (const char*) destination.getCString())); //SendAsync(op, // exportServer[0], // IndicationHandlerService::_handleIndicationCallBack, // this, // (void *)request->queueIds.top()); AutoPtr<AsyncReply> asyncReply(SendWait(asyncRequest.get())); asyncRequest.release(); // Return the ExportIndication results in HandleIndication //response AutoPtr<CIMExportIndicationResponseMessage> exportResponse( reinterpret_cast<CIMExportIndicationResponseMessage *>( (static_cast<AsyncLegacyOperationResult *>( asyncReply.get()))->get_result())); cimException = exportResponse->cimException; this->return_op(op.release()); } else { handleIndicationSuccess = _loadHandler(request, cimException); } } } else if (className.equal (PEGASUS_CLASSNAME_INDHANDLER_SNMP)) { pos = handler.findProperty(PEGASUS_PROPERTYNAME_LSTNRDST_TARGETHOST); if (pos == PEG_NOT_FOUND) { cimException = PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED, MessageLoaderParms( "HandlerService.IndicationHandlerService." "SNMP_HANDLER_WITHOUT_TARGETHOST", "Snmp Handler missing Targethost property")); handleIndicationSuccess = false; } else { CIMProperty prop = handler.getProperty(pos); String destination = prop.getValue().toString(); if (destination.size() == 0) { cimException = PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED, MessageLoaderParms( "HandlerService.IndicationHandlerService." "INVALID_TARGETHOST", "invalid targethost")); handleIndicationSuccess = false; } else { handleIndicationSuccess = _loadHandler(request, cimException); } } } else if ((className.equal (PEGASUS_CLASSNAME_LSTNRDST_SYSTEM_LOG)) || (className.equal (PEGASUS_CLASSNAME_LSTNRDST_EMAIL))) { handleIndicationSuccess = _loadHandler(request, cimException); } // no success to handle indication // somewhere an exception message was build // time to write the error message to the log if (!handleIndicationSuccess) { Logger::put_l(Logger::ERROR_LOG, System::CIMSERVER, Logger::WARNING, MessageLoaderParms( "HandlerService.IndicationHandlerService." "INDICATION_DELIVERY_FAILED", "Failed to deliver an indication: $0", cimException.getMessage())); } CIMHandleIndicationResponseMessage* response = dynamic_cast<CIMHandleIndicationResponseMessage*>( request->buildResponse()); response->cimException = cimException; delete request; PEG_METHOD_EXIT(); return response; }