std::string LLNameValue::printData() const { std::string buffer; switch(mType) { case NVT_STRING: case NVT_ASSET: buffer = mNameValueReference.string; break; case NVT_F32: buffer = llformat("%f", *mNameValueReference.f32); break; case NVT_S32: buffer = llformat("%d", *mNameValueReference.s32); break; case NVT_U32: buffer = llformat("%u", *mNameValueReference.u32); break; case NVT_U64: { char u64_string[U64_BUFFER_LEN]; /* Flawfinder: ignore */ U64_to_str(*mNameValueReference.u64, u64_string, sizeof(u64_string)); buffer = u64_string; } break; case NVT_VEC3: buffer = llformat( "%f, %f, %f", mNameValueReference.vec3->mV[VX], mNameValueReference.vec3->mV[VY], mNameValueReference.vec3->mV[VZ]); break; default: llerrs << "Trying to print unknown NameValue type " << mStringType << llendl; break; } return buffer; }
std::ostream& operator<<(std::ostream& s, const LLNameValue &a) { switch(a.mType) { case NVT_STRING: case NVT_ASSET: s << a.mNameValueReference.string; break; case NVT_F32: s << (*a.mNameValueReference.f32); break; case NVT_S32: s << *(a.mNameValueReference.s32); break; case NVT_U32: s << *(a.mNameValueReference.u32); break; case NVT_U64: { char u64_string[U64_BUFFER_LEN]; /* Flawfinder: ignore */ U64_to_str(*a.mNameValueReference.u64, u64_string, sizeof(u64_string)); s << u64_string; } case NVT_VEC3: s << *(a.mNameValueReference.vec3); break; default: llerrs << "Trying to print unknown NameValue type " << a.mStringType << llendl; break; } return s; }
// Dump out performance metrics over some time interval void LLPerfStats::dumpIntervalPerformanceStats() { // Ensure output file is OK openPerfStatsFile(); if ( mFrameStatsFile ) { LLSD stats = LLSD::emptyMap(); LLStatAccum::TimeScale scale; if ( getReportPerformanceInterval() == 0.f ) { scale = LLStatAccum::SCALE_PER_FRAME; } else if ( getReportPerformanceInterval() < 0.5f ) { scale = LLStatAccum::SCALE_100MS; } else { scale = LLStatAccum::SCALE_SECOND; } // Write LLSD into log stats["utc_time"] = (LLSD::String) LLError::utcTime(); stats["timestamp"] = U64_to_str((totalTime() / 1000) + (gUTCOffset * 1000)); // milliseconds since epoch stats["frame_number"] = (LLSD::Integer) LLFrameTimer::getFrameCount(); // Add process-specific frame info. addProcessFrameInfo(stats, scale); LLPerfBlock::addStatsToLLSDandReset( stats, scale ); mFrameStatsFile << LLSDNotationStreamer(stats) << std::endl; } }
char* U64_to_str(U64 value, char* result, S32 result_size) { std::string res = U64_to_str(value); LLStringUtil::copy(result, res.c_str(), result_size); return result; }
void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user_data*/) { U64 id; std::string local_filename; ELLPath local_path = LL_PATH_NONE; S32 result = LL_ERR_NOERR; LLUUID uuid; LLAssetType::EType type; S16 type_s16; BOOL b_use_big_packets; mesgsys->getBOOL("XferID", "UseBigPackets", b_use_big_packets); mesgsys->getU64Fast(_PREHASH_XferID, _PREHASH_ID, id); char U64_BUF[MAX_STRING]; /* Flawfinder : ignore */ llinfos << "xfer request id: " << U64_to_str(id, U64_BUF, sizeof(U64_BUF)) << " to " << mesgsys->getSender() << llendl; mesgsys->getStringFast(_PREHASH_XferID, _PREHASH_Filename, local_filename); { U8 local_path_u8; mesgsys->getU8("XferID", "FilePath", local_path_u8); local_path = (ELLPath)local_path_u8; } mesgsys->getUUIDFast(_PREHASH_XferID, _PREHASH_VFileID, uuid); mesgsys->getS16Fast(_PREHASH_XferID, _PREHASH_VFileType, type_s16); type = (LLAssetType::EType)type_s16; LLXfer *xferp; if (uuid != LLUUID::null) { if(NULL == LLAssetType::lookup(type)) { llwarns << "Invalid type for xfer request: " << uuid << ":" << type_s16 << " to " << mesgsys->getSender() << llendl; return; } llinfos << "starting vfile transfer: " << uuid << "," << LLAssetType::lookup(type) << " to " << mesgsys->getSender() << llendl; if (! mVFS) { llwarns << "Attempt to send VFile w/o available VFS" << llendl; return; } xferp = (LLXfer *)new LLXfer_VFile(mVFS, uuid, type); if (xferp) { xferp->mNext = mSendList; mSendList = xferp; result = xferp->startSend(id,mesgsys->getSender()); } else { llerrs << "Xfer allcoation error" << llendl; } } else if (!local_filename.empty()) { // See DEV-21775 for detailed security issues if (local_path == LL_PATH_NONE) { // this handles legacy simulators that are passing objects // by giving a filename that explicitly names the cache directory static const std::string legacy_cache_prefix = "data/"; if (remove_prefix(local_filename, legacy_cache_prefix)) { local_path = LL_PATH_CACHE; } } switch (local_path) { case LL_PATH_NONE: if(!validateFileForTransfer(local_filename)) { llwarns << "SECURITY: Unapproved filename '" << local_filename << llendl; return; } break; case LL_PATH_CACHE: if(!verify_cache_filename(local_filename)) { llwarns << "SECURITY: Illegal cache filename '" << local_filename << llendl; return; } break; default: llwarns << "SECURITY: Restricted file dir enum: " << (U32)local_path << llendl; return; } std::string expanded_filename = gDirUtilp->getExpandedFilename( local_path, local_filename ); llinfos << "starting file transfer: " << expanded_filename << " to " << mesgsys->getSender() << llendl; BOOL delete_local_on_completion = FALSE; mesgsys->getBOOL("XferID", "DeleteOnCompletion", delete_local_on_completion); // -1 chunk_size causes it to use the default xferp = (LLXfer *)new LLXfer_File(expanded_filename, delete_local_on_completion, b_use_big_packets ? LL_XFER_LARGE_PAYLOAD : -1); if (xferp) { xferp->mNext = mSendList; mSendList = xferp; result = xferp->startSend(id,mesgsys->getSender()); } else { llerrs << "Xfer allcoation error" << llendl; } } else { char U64_BUF[MAX_STRING]; /* Flawfinder : ignore */ llinfos << "starting memory transfer: " << U64_to_str(id, U64_BUF, sizeof(U64_BUF)) << " to " << mesgsys->getSender() << llendl; xferp = findXfer(id, mSendList); if (xferp) { result = xferp->startSend(id,mesgsys->getSender()); } else { llinfos << "Warning: " << U64_BUF << " not found." << llendl; result = LL_ERR_FILE_NOT_FOUND; } } if (result) { if (xferp) { xferp->abort(result); removeXfer(xferp,&mSendList); } else // can happen with a memory transfer not found { llinfos << "Aborting xfer to " << mesgsys->getSender() << " with error: " << result << llendl; mesgsys->newMessageFast(_PREHASH_AbortXfer); mesgsys->nextBlockFast(_PREHASH_XferID); mesgsys->addU64Fast(_PREHASH_ID, id); mesgsys->addS32Fast(_PREHASH_Result, result); mesgsys->sendMessage(mesgsys->getSender()); } } else if(xferp && (numActiveXfers(xferp->mRemoteHost) < mMaxOutgoingXfersPerCircuit)) { xferp->sendNextPacket(); changeNumActiveXfers(xferp->mRemoteHost,1); // llinfos << "***STARTING XFER IMMEDIATELY***" << llendl; } else { if(xferp) { llinfos << " queueing xfer request, " << numPendingXfers(xferp->mRemoteHost) << " ahead of this one" << llendl; } else { llwarns << "LLXferManager::processFileRequest() - no xfer found!" << llendl; } } }
void LLXferManager::processReceiveData (LLMessageSystem *mesgsys, void ** /*user_data*/) { // there's sometimes an extra 4 bytes added to an xfer payload const S32 BUF_SIZE = LL_XFER_LARGE_PAYLOAD + 4; char fdata_buf[LL_XFER_LARGE_PAYLOAD + 4]; /* Flawfinder : ignore */ S32 fdata_size; U64 id; S32 packetnum; LLXfer * xferp; mesgsys->getU64Fast(_PREHASH_XferID, _PREHASH_ID, id); mesgsys->getS32Fast(_PREHASH_XferID, _PREHASH_Packet, packetnum); fdata_size = mesgsys->getSizeFast(_PREHASH_DataPacket,_PREHASH_Data); mesgsys->getBinaryDataFast(_PREHASH_DataPacket, _PREHASH_Data, fdata_buf, 0, 0, BUF_SIZE); xferp = findXfer(id, mReceiveList); if (!xferp) { char U64_BUF[MAX_STRING]; /* Flawfinder : ignore */ llwarns << "received xfer data from " << mesgsys->getSender() << " for non-existent xfer id: " << U64_to_str(id, U64_BUF, sizeof(U64_BUF)) << llendl; return; } S32 xfer_size; if (decodePacketNum(packetnum) != xferp->mPacketNum) // is the packet different from what we were expecting? { // confirm it if it was a resend of the last one, since the confirmation might have gotten dropped if (decodePacketNum(packetnum) == (xferp->mPacketNum - 1)) { llinfos << "Reconfirming xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << " packet " << packetnum << llendl; sendConfirmPacket(mesgsys, id, decodePacketNum(packetnum), mesgsys->getSender()); } else { llinfos << "Ignoring xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << " recv'd packet " << packetnum << "; expecting " << xferp->mPacketNum << llendl; } return; } S32 result = 0; if (xferp->mPacketNum == 0) // first packet has size encoded as additional S32 at beginning of data { ntohmemcpy(&xfer_size,fdata_buf,MVT_S32,sizeof(S32)); // do any necessary things on first packet ie. allocate memory xferp->setXferSize(xfer_size); // adjust buffer start and size result = xferp->receiveData(&(fdata_buf[sizeof(S32)]),fdata_size-(sizeof(S32))); } else { result = xferp->receiveData(fdata_buf,fdata_size); } if (result == LL_ERR_CANNOT_OPEN_FILE) { xferp->abort(LL_ERR_CANNOT_OPEN_FILE); removeXfer(xferp,&mReceiveList); startPendingDownloads(); return; } xferp->mPacketNum++; // expect next packet if (!mUseAckThrottling) { // No throttling, confirm right away sendConfirmPacket(mesgsys, id, decodePacketNum(packetnum), mesgsys->getSender()); } else { // Throttling, put on queue to be confirmed later. LLXferAckInfo ack_info; ack_info.mID = id; ack_info.mPacketNum = decodePacketNum(packetnum); ack_info.mRemoteHost = mesgsys->getSender(); mXferAckQueue.push(ack_info); } if (isLastPacket(packetnum)) { xferp->processEOF(); removeXfer(xferp,&mReceiveList); startPendingDownloads(); } }
std::string LLXfer::getFileName() { return U64_to_str(mID); }