//============================================================================= // Entry Point //============================================================================= RU32 RPAL_THREAD_FUNC RpHcpI_mainThread ( rEvent isTimeToStop ) { RU32 ret = 0; RU64 nextBeaconTime = 0; rList cloudMessages = NULL; rSequence msg = NULL; rList newConfigurations = NULL; rList newNotifications = NULL; RPU8 newConfigurationHash = NULL; RU32 newHashSize = 0; rSequence staticConfig = NULL; RU8* tmpBuffer = NULL; RU32 tmpSize = 0; FORCE_LINK_THAT( HCP_IFACE ); CryptoLib_init(); getPrivileges(); // This is the event for the collectors, it is different than the // hbs proper event so that we can restart the collectors without // signaling hbs as a whole. if( NULL == ( g_hbs_state.isTimeToStop = rEvent_create( TRUE ) ) ) { return (RU32)-1; } // By default, no collectors are running rEvent_set( g_hbs_state.isTimeToStop ); // We attempt to load some initial config from the serialized // rSequence that can be patched in this binary. if( NULL != ( staticConfig = getStaticConfig() ) ) { if( rSequence_getBUFFER( staticConfig, RP_TAGS_HBS_ROOT_PUBLIC_KEY, &tmpBuffer, &tmpSize ) ) { hbs_cloud_pub_key = rpal_memory_duplicate( tmpBuffer, tmpSize ); if( NULL == hbs_cloud_pub_key ) { hbs_cloud_pub_key = hbs_cloud_default_pub_key; } rpal_debug_info( "loading hbs root public key from static config" ); } if( rSequence_getRU32( staticConfig, RP_TAGS_MAX_QUEUE_SIZE, &g_hbs_state.maxQueueNum ) ) { rpal_debug_info( "loading max queue size from static config" ); } else { g_hbs_state.maxQueueNum = HBS_EXFIL_QUEUE_MAX_NUM; } if( rSequence_getRU32( staticConfig, RP_TAGS_MAX_SIZE, &g_hbs_state.maxQueueSize ) ) { rpal_debug_info( "loading max queue num from static config" ); } else { g_hbs_state.maxQueueSize = HBS_EXFIL_QUEUE_MAX_SIZE; } rSequence_free( staticConfig ); } else { hbs_cloud_pub_key = hbs_cloud_default_pub_key; g_hbs_state.maxQueueNum = HBS_EXFIL_QUEUE_MAX_NUM; g_hbs_state.maxQueueSize = HBS_EXFIL_QUEUE_MAX_SIZE; } if( !rQueue_create( &g_hbs_state.outQueue, freeExfilEvent, g_hbs_state.maxQueueNum ) ) { rEvent_free( g_hbs_state.isTimeToStop ); return (RU32)-1; } // We simply enqueue a message to let the cloud know we're starting sendStartupEvent(); while( !rEvent_wait( isTimeToStop, (RU32)nextBeaconTime ) ) { nextBeaconTime = MSEC_FROM_SEC( HBS_DEFAULT_BEACON_TIMEOUT + ( rpal_rand() % HBS_DEFAULT_BEACON_TIMEOUT_FUZZ ) ); if( NULL != ( cloudMessages = beaconHome() ) ) { while( rList_getSEQUENCE( cloudMessages, RP_TAGS_MESSAGE, &msg ) ) { // Cloud message indicating next requested beacon time, as a Seconds delta if( rSequence_getTIMEDELTA( msg, RP_TAGS_TIMEDELTA, &nextBeaconTime ) ) { nextBeaconTime = MSEC_FROM_SEC( nextBeaconTime ); rpal_debug_info( "received set_next_beacon" ); } if( NULL == newConfigurations && rSequence_getLIST( msg, RP_TAGS_HBS_CONFIGURATIONS, &newConfigurations ) ) { rpal_debug_info( "received a new profile" ); if( rSequence_getBUFFER( msg, RP_TAGS_HASH, &newConfigurationHash, &newHashSize ) && newHashSize == CRYPTOLIB_HASH_SIZE ) { newConfigurations = rList_duplicate( newConfigurations ); rpal_memory_memcpy( &( g_hbs_state.currentConfigHash ), newConfigurationHash, CRYPTOLIB_HASH_SIZE ); g_hbs_state.isProfilePresent = TRUE; } else { newConfigurations = NULL; rpal_debug_error( "profile hash received is invalid" ); } } if( NULL == newNotifications && rSequence_getLIST( msg, RP_TAGS_HBS_CLOUD_NOTIFICATIONS, &newNotifications ) ) { rpal_debug_info( "received cloud events" ); newNotifications = rList_duplicate( newNotifications ); } } rList_free( cloudMessages ); } // If this is the initial boot and we have no profile yet, we'll load a dummy // blank profile and use our defaults. if( NULL == newConfigurations && !g_hbs_state.isProfilePresent && !rEvent_wait( isTimeToStop, 0 ) ) { newConfigurations = rList_new( RP_TAGS_HCP_MODULES, RPCM_SEQUENCE ); rpal_debug_info( "setting empty profile" ); } if( NULL != newConfigurations ) { // We try to be as responsive as possible when asked to quit // so if we happen to have received the signal during a beacon // we will action the quit instead of the config change. if( !rEvent_wait( isTimeToStop, 0 ) ) { rpal_debug_info( "begining sensor update on new profile" ); shutdownCollectors(); updateCollectorConfigs( newConfigurations ); rList_free( newConfigurations ); newConfigurations = NULL; startCollectors(); } else { rList_free( newConfigurations ); } newConfigurations = NULL; } if( NULL != newNotifications ) { if( !rEvent_wait( isTimeToStop, 0 ) ) { publishCloudNotifications( newNotifications ); } rList_free( newNotifications ); newNotifications = NULL; } } // We issue one last beacon indicating we are stopping sendShutdownEvent(); // Shutdown everything shutdownCollectors(); // Cleanup the last few resources rEvent_free( g_hbs_state.isTimeToStop ); rQueue_free( g_hbs_state.outQueue ); CryptoLib_deinit(); if( hbs_cloud_default_pub_key != hbs_cloud_pub_key && NULL != hbs_cloud_pub_key ) { rpal_memory_free( hbs_cloud_pub_key ); hbs_cloud_pub_key = NULL; } return ret; }
NARoutine::NARoutine(const QualifiedName &name, const TrafDesc *routine_desc, BindWA *bindWA, Int32 &errorOccurred, NAMemory *heap) : name_ (name, heap) , hashKey_ (name, heap) , language_ (routine_desc->routineDesc()->language) , UDRType_ (routine_desc->routineDesc()->UDRType) , sqlAccess_ (routine_desc->routineDesc()->sqlAccess) , transactionAttributes_ (routine_desc->routineDesc()->transactionAttributes) , maxResults_ (routine_desc->routineDesc()->maxResults) , stateAreaSize_ (routine_desc->routineDesc()->stateAreaSize) , externalFile_ ("", heap) , externalPath_ (routine_desc->routineDesc()->libraryFileName, heap) , externalName_ ("", heap) , librarySqlName_ (routine_desc->routineDesc()->librarySqlName, COM_UNKNOWN_NAME, FALSE, heap) //TODO , signature_ (routine_desc->routineDesc()->signature, heap) , paramStyle_ (routine_desc->routineDesc()->paramStyle) , paramStyleVersion_ (COM_ROUTINE_PARAM_STYLE_VERSION_1) , isDeterministic_ (routine_desc->routineDesc()->isDeterministic) , isCallOnNull_ (routine_desc->routineDesc()->isCallOnNull ) , isIsolate_ (routine_desc->routineDesc()->isIsolate) , externalSecurity_ (routine_desc->routineDesc()->externalSecurity) , isExtraCall_ (FALSE) //TODO , hasOutParams_ (FALSE) , redefTime_ (0) //TODO , lastUsedTime_ (0) , routineSecKeySet_ (heap) , passThruDataNumEntries_ (0) , passThruData_ (NULL) , passThruDataSize_ (0) , udfFanOut_ (1) // TODO , uecValues_ (heap,0) , isUniversal_ (0) // TODO , actionPosition_ (0) // TODO , executionMode_ (COM_ROUTINE_SAFE_EXECUTION) , objectUID_ (routine_desc->routineDesc()->objectUID) , dllName_ (routine_desc->routineDesc()->libraryFileName, heap) , dllEntryPoint_ (routine_desc->routineDesc()->externalName, heap) , sasFormatWidth_ ("", heap) //TODO , systemName_ ("", heap) // TODO , dataSource_ ("", heap) // TODO , fileSuffix_ ("", heap) // TODO , schemaVersionOfRoutine_ ((COM_VERSION)0) // TODO , objectOwner_ (routine_desc->routineDesc()->owner) , schemaOwner_ (routine_desc->routineDesc()->schemaOwner) , privInfo_ (NULL) , heap_(heap) { char parallelism[5]; CmGetComRoutineParallelismAsLit(routine_desc->routineDesc()->parallelism, parallelism); comRoutineParallelism_ = ((char *)parallelism); if (paramStyle_ == COM_STYLE_JAVA_CALL) { NAString extName(routine_desc->routineDesc()->externalName); size_t pos=extName.last('.'); externalName_ = extName(pos+1, (extName.length()-pos-1)); // method_name externalFile_ = extName.remove (pos); // package_name.class_name } else { externalName_ = routine_desc->routineDesc()->externalName; if (language_ == COM_LANGUAGE_C || language_ == COM_LANGUAGE_CPP) { // Split the fully-qualified DLL name into a directory name and // simple file name ComUInt32 len = dllName_.length(); if (len > 0) { size_t lastSlash = dllName_.last('/'); if (lastSlash == NA_NPOS) { // No slash was found externalPath_ = "."; externalFile_ = dllName_; } else { // A slash was found. EXTERNAL PATH is everything before the // slash. EXTERNAL FILE is everything after. externalPath_ = dllName_; externalPath_.remove(lastSlash, len - lastSlash); externalFile_ = dllName_; externalFile_.remove(0, lastSlash + 1); } } } // if (len > 0) } ComSInt32 colCount = routine_desc->routineDesc()->paramsCount; NAColumn *newCol = NULL; NAType *newColType = NULL; extRoutineName_ = new (heap) ExtendedQualName( name_, heap ); extActionName_ = new (heap) NAString(heap); intActionName_ = new (heap) ComObjectName(heap); params_ = new (heap) NAColumnArray(heap); inParams_ = new (heap) NAColumnArray(heap); outParams_ = new (heap) NAColumnArray(heap); // to compute java signature ComFSDataType *paramType = new STMTHEAP ComFSDataType[colCount]; ComUInt32 *subType = new STMTHEAP ComUInt32 [colCount]; ComColumnDirection *direction = new STMTHEAP ComColumnDirection[colCount] ; // // Construct the CostVectors // CQDs are checked at Bind time. Int32 initCpuCost = -1; Int32 initIOCost = -1; Int32 initMsgCost = -1; CostScalar initialCpuCost( initCpuCost); CostScalar initialIOCost( initIOCost); CostScalar initialMsgCost( initMsgCost); initialRowCost_.setCPUTime( initCpuCost < 0 ? csMinusOne : initialCpuCost); initialRowCost_.setIOTime( initIOCost < 0 ? csMinusOne : initialIOCost); initialRowCost_.setMSGTime( initMsgCost < 0 ? csMinusOne : initialMsgCost); Int32 normCpuCost = -1; Int32 normIOCost = -1; Int32 normMsgCost = -1; CostScalar normalCpuCost( normCpuCost); CostScalar normalIOCost( normIOCost); CostScalar normalMsgCost( normMsgCost); normalRowCost_.setCPUTime( normCpuCost < 0 ? csMinusOne : normalCpuCost); normalRowCost_.setIOTime( normIOCost < 0 ? csMinusOne : normalIOCost); normalRowCost_.setMSGTime( normMsgCost < 0 ? csMinusOne : normalMsgCost); TrafDesc *params_desc_list = routine_desc->routineDesc()->params; TrafColumnsDesc *param_desc; int i = 0; while (params_desc_list) { param_desc = params_desc_list->columnsDesc(); // Create the new NAType. if (NAColumn::createNAType(param_desc->columnsDesc(), (const NATable *)NULL, newColType, heap_)) { errorOccurred = TRUE; return; } if (param_desc->colname && strncmp(param_desc->colname, "#:", 2) == 0) { memset(param_desc->colname, 0, 2); } ComParamDirection colDirection = param_desc->paramDirection(); // Create the new NAColumn and insert it into the NAColumnArray newCol = new (heap) NAColumn( (const char *)UDRCopyString (param_desc->colname, heap) , param_desc->colnumber , newColType , heap , NULL // NATable * , USER_COLUMN , COM_NO_DEFAULT , NULL // default value , UDRCopyString("", heap) // TODO:heading can it have some value , param_desc->isUpshifted() , FALSE // addedColumn , (ComColumnDirection) colDirection , param_desc->isOptional() , (char *) COM_NORMAL_PARAM_TYPE_LIT ); // We have to check for INOUT in both the // if's below if ( COM_OUTPUT_PARAM == colDirection || COM_INOUT_PARAM == colDirection ) { hasOutParams_ = TRUE; outParams_->insert (newCol); params_->insert (newCol ); } if ( COM_INPUT_PARAM == colDirection || COM_INOUT_PARAM == colDirection ) { inParams_->insert (newCol); if ( COM_INOUT_PARAM != colDirection ) { params_->insert (newCol ); } // if not INOUT } // if IN or INOUT // Gather the param attributes for LM from the paramDefArray previously // populated and from the routineparamList generated from paramDefArray. paramType[i] = (ComFSDataType)newColType->getFSDatatype(); subType[i] = 0; // default // Set subType for special cases detected by LM switch ( paramType[i] ) { case COM_SIGNED_BIN16_FSDT : case COM_SIGNED_BIN32_FSDT : case COM_SIGNED_BIN64_FSDT : case COM_UNSIGNED_BIN16_FSDT : case COM_UNSIGNED_BIN32_FSDT : case COM_UNSIGNED_BPINT_FSDT : { subType[i] = newColType->getPrecision(); break; } case COM_DATETIME_FSDT : { switch ( ((DatetimeType *)newColType)->getSubtype() ) { case DatetimeType::SUBTYPE_SQLDate : subType[i] = 1; break; case DatetimeType::SUBTYPE_SQLTime : subType[i] = 2; break; case DatetimeType::SUBTYPE_SQLTimestamp : subType[i] = 3; break; } } } // end switch paramType[i] direction[i] = (ComColumnDirection) colDirection; params_desc_list = params_desc_list->next; i++; } // for passThruDataNumEntries_ = 0; passThruData_ = NULL; passThruDataSize_ = NULL; #define MAX_SIGNATURE_LENGTH 8193 if ((language_ == COM_LANGUAGE_JAVA)&&(signature_.length() < 2)) { // Allocate buffer for generated signature char sigBuf[MAX_SIGNATURE_LENGTH]; sigBuf[0] = '\0'; // If the syntax specified a signature, pass that to LanguageManager. char* optionalSig = NULL; ComBoolean isJavaMain = ((str_cmp_ne(externalName_.data(), "main") == 0) ? TRUE : FALSE); LmResult createSigResult; LmJavaSignature *lmSignature = new (STMTHEAP) LmJavaSignature(NULL, STMTHEAP); createSigResult = lmSignature->createSig(paramType, subType, direction, colCount, COM_UNKNOWN_FSDT, 0, maxResults_, optionalSig, isJavaMain, sigBuf, MAX_SIGNATURE_LENGTH, CmpCommon::diags()); NADELETE(lmSignature, LmJavaSignature, STMTHEAP); // Lm returned error. Lm fills diags area if (createSigResult != LM_ERR) signature_ = sigBuf; } getPrivileges(routine_desc->routineDesc()->priv_desc); heapSize_ = (heap ? heap->getTotalSize() : 0); }