PageRenderTime 51ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

/indra/llmessage/lltemplatemessagereader.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 828 lines | 633 code | 114 blank | 81 comment | 88 complexity | 4c11c0d6aa5b1e83c3cfc470d2b8f0ac MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file lltemplatemessagereader.cpp
  3. * @brief LLTemplateMessageReader class implementation.
  4. *
  5. * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #include "linden_common.h"
  27. #include "lltemplatemessagereader.h"
  28. #include "llfasttimer.h"
  29. #include "llmessagebuilder.h"
  30. #include "llmessagetemplate.h"
  31. #include "llmath.h"
  32. #include "llquaternion.h"
  33. #include "message.h"
  34. #include "u64.h"
  35. #include "v3dmath.h"
  36. #include "v3math.h"
  37. #include "v4math.h"
  38. LLTemplateMessageReader::LLTemplateMessageReader(message_template_number_map_t&
  39. number_template_map) :
  40. mReceiveSize(0),
  41. mCurrentRMessageTemplate(NULL),
  42. mCurrentRMessageData(NULL),
  43. mMessageNumbers(number_template_map)
  44. {
  45. }
  46. //virtual
  47. LLTemplateMessageReader::~LLTemplateMessageReader()
  48. {
  49. delete mCurrentRMessageData;
  50. mCurrentRMessageData = NULL;
  51. }
  52. //virtual
  53. void LLTemplateMessageReader::clearMessage()
  54. {
  55. mReceiveSize = -1;
  56. mCurrentRMessageTemplate = NULL;
  57. delete mCurrentRMessageData;
  58. mCurrentRMessageData = NULL;
  59. }
  60. void LLTemplateMessageReader::getData(const char *blockname, const char *varname, void *datap, S32 size, S32 blocknum, S32 max_size)
  61. {
  62. // is there a message ready to go?
  63. if (mReceiveSize == -1)
  64. {
  65. llerrs << "No message waiting for decode 2!" << llendl;
  66. return;
  67. }
  68. if (!mCurrentRMessageData)
  69. {
  70. llerrs << "Invalid mCurrentMessageData in getData!" << llendl;
  71. return;
  72. }
  73. char *bnamep = (char *)blockname + blocknum; // this works because it's just a hash. The bnamep is never derefference
  74. char *vnamep = (char *)varname;
  75. LLMsgData::msg_blk_data_map_t::const_iterator iter = mCurrentRMessageData->mMemberBlocks.find(bnamep);
  76. if (iter == mCurrentRMessageData->mMemberBlocks.end())
  77. {
  78. llerrs << "Block " << blockname << " #" << blocknum
  79. << " not in message " << mCurrentRMessageData->mName << llendl;
  80. return;
  81. }
  82. LLMsgBlkData *msg_block_data = iter->second;
  83. LLMsgVarData& vardata = msg_block_data->mMemberVarData[vnamep];
  84. if (!vardata.getName())
  85. {
  86. llerrs << "Variable "<< vnamep << " not in message "
  87. << mCurrentRMessageData->mName<< " block " << bnamep << llendl;
  88. return;
  89. }
  90. if (size && size != vardata.getSize())
  91. {
  92. llerrs << "Msg " << mCurrentRMessageData->mName
  93. << " variable " << vnamep
  94. << " is size " << vardata.getSize()
  95. << " but copying into buffer of size " << size
  96. << llendl;
  97. return;
  98. }
  99. const S32 vardata_size = vardata.getSize();
  100. if( max_size >= vardata_size )
  101. {
  102. switch( vardata_size )
  103. {
  104. case 1:
  105. *((U8*)datap) = *((U8*)vardata.getData());
  106. break;
  107. case 2:
  108. *((U16*)datap) = *((U16*)vardata.getData());
  109. break;
  110. case 4:
  111. *((U32*)datap) = *((U32*)vardata.getData());
  112. break;
  113. case 8:
  114. ((U32*)datap)[0] = ((U32*)vardata.getData())[0];
  115. ((U32*)datap)[1] = ((U32*)vardata.getData())[1];
  116. break;
  117. default:
  118. memcpy(datap, vardata.getData(), vardata_size);
  119. break;
  120. }
  121. }
  122. else
  123. {
  124. llwarns << "Msg " << mCurrentRMessageData->mName
  125. << " variable " << vnamep
  126. << " is size " << vardata.getSize()
  127. << " but truncated to max size of " << max_size
  128. << llendl;
  129. memcpy(datap, vardata.getData(), max_size);
  130. }
  131. }
  132. S32 LLTemplateMessageReader::getNumberOfBlocks(const char *blockname)
  133. {
  134. // is there a message ready to go?
  135. if (mReceiveSize == -1)
  136. {
  137. llerrs << "No message waiting for decode 3!" << llendl;
  138. return -1;
  139. }
  140. if (!mCurrentRMessageData)
  141. {
  142. llerrs << "Invalid mCurrentRMessageData in getData!" << llendl;
  143. return -1;
  144. }
  145. char *bnamep = (char *)blockname;
  146. LLMsgData::msg_blk_data_map_t::const_iterator iter = mCurrentRMessageData->mMemberBlocks.find(bnamep);
  147. if (iter == mCurrentRMessageData->mMemberBlocks.end())
  148. {
  149. return 0;
  150. }
  151. return (iter->second)->mBlockNumber;
  152. }
  153. S32 LLTemplateMessageReader::getSize(const char *blockname, const char *varname)
  154. {
  155. // is there a message ready to go?
  156. if (mReceiveSize == -1)
  157. { // This is a serious error - crash
  158. llerrs << "No message waiting for decode 4!" << llendl;
  159. return LL_MESSAGE_ERROR;
  160. }
  161. if (!mCurrentRMessageData)
  162. { // This is a serious error - crash
  163. llerrs << "Invalid mCurrentRMessageData in getData!" << llendl;
  164. return LL_MESSAGE_ERROR;
  165. }
  166. char *bnamep = (char *)blockname;
  167. LLMsgData::msg_blk_data_map_t::const_iterator iter = mCurrentRMessageData->mMemberBlocks.find(bnamep);
  168. if (iter == mCurrentRMessageData->mMemberBlocks.end())
  169. { // don't crash
  170. llinfos << "Block " << bnamep << " not in message "
  171. << mCurrentRMessageData->mName << llendl;
  172. return LL_BLOCK_NOT_IN_MESSAGE;
  173. }
  174. char *vnamep = (char *)varname;
  175. LLMsgBlkData* msg_data = iter->second;
  176. LLMsgVarData& vardata = msg_data->mMemberVarData[vnamep];
  177. if (!vardata.getName())
  178. { // don't crash
  179. llinfos << "Variable " << varname << " not in message "
  180. << mCurrentRMessageData->mName << " block " << bnamep << llendl;
  181. return LL_VARIABLE_NOT_IN_BLOCK;
  182. }
  183. if (mCurrentRMessageTemplate->mMemberBlocks[bnamep]->mType != MBT_SINGLE)
  184. { // This is a serious error - crash
  185. llerrs << "Block " << bnamep << " isn't type MBT_SINGLE,"
  186. " use getSize with blocknum argument!" << llendl;
  187. return LL_MESSAGE_ERROR;
  188. }
  189. return vardata.getSize();
  190. }
  191. S32 LLTemplateMessageReader::getSize(const char *blockname, S32 blocknum, const char *varname)
  192. {
  193. // is there a message ready to go?
  194. if (mReceiveSize == -1)
  195. { // This is a serious error - crash
  196. llerrs << "No message waiting for decode 5!" << llendl;
  197. return LL_MESSAGE_ERROR;
  198. }
  199. if (!mCurrentRMessageData)
  200. { // This is a serious error - crash
  201. llerrs << "Invalid mCurrentRMessageData in getData!" << llendl;
  202. return LL_MESSAGE_ERROR;
  203. }
  204. char *bnamep = (char *)blockname + blocknum;
  205. char *vnamep = (char *)varname;
  206. LLMsgData::msg_blk_data_map_t::const_iterator iter = mCurrentRMessageData->mMemberBlocks.find(bnamep);
  207. if (iter == mCurrentRMessageData->mMemberBlocks.end())
  208. { // don't crash
  209. llinfos << "Block " << bnamep << " not in message "
  210. << mCurrentRMessageData->mName << llendl;
  211. return LL_BLOCK_NOT_IN_MESSAGE;
  212. }
  213. LLMsgBlkData* msg_data = iter->second;
  214. LLMsgVarData& vardata = msg_data->mMemberVarData[vnamep];
  215. if (!vardata.getName())
  216. { // don't crash
  217. llinfos << "Variable " << vnamep << " not in message "
  218. << mCurrentRMessageData->mName << " block " << bnamep << llendl;
  219. return LL_VARIABLE_NOT_IN_BLOCK;
  220. }
  221. return vardata.getSize();
  222. }
  223. void LLTemplateMessageReader::getBinaryData(const char *blockname,
  224. const char *varname, void *datap,
  225. S32 size, S32 blocknum,
  226. S32 max_size)
  227. {
  228. getData(blockname, varname, datap, size, blocknum, max_size);
  229. }
  230. void LLTemplateMessageReader::getS8(const char *block, const char *var,
  231. S8 &u, S32 blocknum)
  232. {
  233. getData(block, var, &u, sizeof(S8), blocknum);
  234. }
  235. void LLTemplateMessageReader::getU8(const char *block, const char *var,
  236. U8 &u, S32 blocknum)
  237. {
  238. getData(block, var, &u, sizeof(U8), blocknum);
  239. }
  240. void LLTemplateMessageReader::getBOOL(const char *block, const char *var,
  241. BOOL &b, S32 blocknum )
  242. {
  243. U8 value;
  244. getData(block, var, &value, sizeof(U8), blocknum);
  245. b = (BOOL) value;
  246. }
  247. void LLTemplateMessageReader::getS16(const char *block, const char *var,
  248. S16 &d, S32 blocknum)
  249. {
  250. getData(block, var, &d, sizeof(S16), blocknum);
  251. }
  252. void LLTemplateMessageReader::getU16(const char *block, const char *var,
  253. U16 &d, S32 blocknum)
  254. {
  255. getData(block, var, &d, sizeof(U16), blocknum);
  256. }
  257. void LLTemplateMessageReader::getS32(const char *block, const char *var,
  258. S32 &d, S32 blocknum)
  259. {
  260. getData(block, var, &d, sizeof(S32), blocknum);
  261. }
  262. void LLTemplateMessageReader::getU32(const char *block, const char *var,
  263. U32 &d, S32 blocknum)
  264. {
  265. getData(block, var, &d, sizeof(U32), blocknum);
  266. }
  267. void LLTemplateMessageReader::getU64(const char *block, const char *var,
  268. U64 &d, S32 blocknum)
  269. {
  270. getData(block, var, &d, sizeof(U64), blocknum);
  271. }
  272. void LLTemplateMessageReader::getF32(const char *block, const char *var,
  273. F32 &d, S32 blocknum)
  274. {
  275. getData(block, var, &d, sizeof(F32), blocknum);
  276. if( !llfinite( d ) )
  277. {
  278. llwarns << "non-finite in getF32Fast " << block << " " << var
  279. << llendl;
  280. d = 0;
  281. }
  282. }
  283. void LLTemplateMessageReader::getF64(const char *block, const char *var,
  284. F64 &d, S32 blocknum)
  285. {
  286. getData(block, var, &d, sizeof(F64), blocknum);
  287. if( !llfinite( d ) )
  288. {
  289. llwarns << "non-finite in getF64Fast " << block << " " << var
  290. << llendl;
  291. d = 0;
  292. }
  293. }
  294. void LLTemplateMessageReader::getVector3(const char *block, const char *var,
  295. LLVector3 &v, S32 blocknum )
  296. {
  297. getData(block, var, &v.mV[0], sizeof(v.mV), blocknum);
  298. if( !v.isFinite() )
  299. {
  300. llwarns << "non-finite in getVector3Fast " << block << " "
  301. << var << llendl;
  302. v.zeroVec();
  303. }
  304. }
  305. void LLTemplateMessageReader::getVector4(const char *block, const char *var,
  306. LLVector4 &v, S32 blocknum)
  307. {
  308. getData(block, var, &v.mV[0], sizeof(v.mV), blocknum);
  309. if( !v.isFinite() )
  310. {
  311. llwarns << "non-finite in getVector4Fast " << block << " "
  312. << var << llendl;
  313. v.zeroVec();
  314. }
  315. }
  316. void LLTemplateMessageReader::getVector3d(const char *block, const char *var,
  317. LLVector3d &v, S32 blocknum )
  318. {
  319. getData(block, var, &v.mdV[0], sizeof(v.mdV), blocknum);
  320. if( !v.isFinite() )
  321. {
  322. llwarns << "non-finite in getVector3dFast " << block << " "
  323. << var << llendl;
  324. v.zeroVec();
  325. }
  326. }
  327. void LLTemplateMessageReader::getQuat(const char *block, const char *var,
  328. LLQuaternion &q, S32 blocknum)
  329. {
  330. LLVector3 vec;
  331. getData(block, var, &vec.mV[0], sizeof(vec.mV), blocknum);
  332. if( vec.isFinite() )
  333. {
  334. q.unpackFromVector3( vec );
  335. }
  336. else
  337. {
  338. llwarns << "non-finite in getQuatFast " << block << " " << var
  339. << llendl;
  340. q.loadIdentity();
  341. }
  342. }
  343. void LLTemplateMessageReader::getUUID(const char *block, const char *var,
  344. LLUUID &u, S32 blocknum)
  345. {
  346. getData(block, var, &u.mData[0], sizeof(u.mData), blocknum);
  347. }
  348. inline void LLTemplateMessageReader::getIPAddr(const char *block, const char *var, U32 &u, S32 blocknum)
  349. {
  350. getData(block, var, &u, sizeof(U32), blocknum);
  351. }
  352. inline void LLTemplateMessageReader::getIPPort(const char *block, const char *var, U16 &u, S32 blocknum)
  353. {
  354. getData(block, var, &u, sizeof(U16), blocknum);
  355. u = ntohs(u);
  356. }
  357. inline void LLTemplateMessageReader::getString(const char *block, const char *var, S32 buffer_size, char *s, S32 blocknum )
  358. {
  359. s[0] = '\0';
  360. getData(block, var, s, 0, blocknum, buffer_size);
  361. s[buffer_size - 1] = '\0';
  362. }
  363. inline void LLTemplateMessageReader::getString(const char *block, const char *var, std::string& outstr, S32 blocknum )
  364. {
  365. char s[MTUBYTES + 1]= {0}; // every element is initialized with 0
  366. getData(block, var, s, 0, blocknum, MTUBYTES);
  367. s[MTUBYTES] = '\0';
  368. outstr = s;
  369. }
  370. //virtual
  371. S32 LLTemplateMessageReader::getMessageSize() const
  372. {
  373. return mReceiveSize;
  374. }
  375. // Returns template for the message contained in buffer
  376. BOOL LLTemplateMessageReader::decodeTemplate(
  377. const U8* buffer, S32 buffer_size, // inputs
  378. LLMessageTemplate** msg_template ) // outputs
  379. {
  380. const U8* header = buffer + LL_PACKET_ID_SIZE;
  381. // is there a message ready to go?
  382. if (buffer_size <= 0)
  383. {
  384. llwarns << "No message waiting for decode!" << llendl;
  385. return(FALSE);
  386. }
  387. U32 num = 0;
  388. if (header[0] != 255)
  389. {
  390. // high frequency message
  391. num = header[0];
  392. }
  393. else if ((buffer_size >= ((S32) LL_MINIMUM_VALID_PACKET_SIZE + 1)) && (header[1] != 255))
  394. {
  395. // medium frequency message
  396. num = (255 << 8) | header[1];
  397. }
  398. else if ((buffer_size >= ((S32) LL_MINIMUM_VALID_PACKET_SIZE + 3)) && (header[1] == 255))
  399. {
  400. // low frequency message
  401. U16 message_id_U16 = 0;
  402. // I think this check busts the message system.
  403. // it appears that if there is a NULL in the message #, it won't copy it....
  404. // what was the goal?
  405. //if(header[2])
  406. memcpy(&message_id_U16, &header[2], 2);
  407. // dependant on endian-ness:
  408. // U32 temp = (255 << 24) | (255 << 16) | header[2];
  409. // independant of endian-ness:
  410. message_id_U16 = ntohs(message_id_U16);
  411. num = 0xFFFF0000 | message_id_U16;
  412. }
  413. else // bogus packet received (too short)
  414. {
  415. llwarns << "Packet with unusable length received (too short): "
  416. << buffer_size << llendl;
  417. return(FALSE);
  418. }
  419. LLMessageTemplate* temp = get_ptr_in_map(mMessageNumbers,num);
  420. if (temp)
  421. {
  422. *msg_template = temp;
  423. }
  424. else
  425. {
  426. llwarns << "Message #" << std::hex << num << std::dec
  427. << " received but not registered!" << llendl;
  428. gMessageSystem->callExceptionFunc(MX_UNREGISTERED_MESSAGE);
  429. return(FALSE);
  430. }
  431. return(TRUE);
  432. }
  433. void LLTemplateMessageReader::logRanOffEndOfPacket( const LLHost& host, const S32 where, const S32 wanted )
  434. {
  435. // we've run off the end of the packet!
  436. llwarns << "Ran off end of packet " << mCurrentRMessageTemplate->mName
  437. // << " with id " << mCurrentRecvPacketID
  438. << " from " << host
  439. << " trying to read " << wanted
  440. << " bytes at position " << where
  441. << " going past packet end at " << mReceiveSize
  442. << llendl;
  443. if(gMessageSystem->mVerboseLog)
  444. {
  445. llinfos << "MSG: -> " << host << "\tREAD PAST END:\t"
  446. // << mCurrentRecvPacketID << " "
  447. << getMessageName() << llendl;
  448. }
  449. gMessageSystem->callExceptionFunc(MX_RAN_OFF_END_OF_PACKET);
  450. }
  451. static LLFastTimer::DeclareTimer FTM_PROCESS_MESSAGES("Process Messages");
  452. // decode a given message
  453. BOOL LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender )
  454. {
  455. llassert( mReceiveSize >= 0 );
  456. llassert( mCurrentRMessageTemplate);
  457. llassert( !mCurrentRMessageData );
  458. delete mCurrentRMessageData; // just to make sure
  459. // The offset tells us how may bytes to skip after the end of the
  460. // message name.
  461. U8 offset = buffer[PHL_OFFSET];
  462. S32 decode_pos = LL_PACKET_ID_SIZE + (S32)(mCurrentRMessageTemplate->mFrequency) + offset;
  463. // create base working data set
  464. mCurrentRMessageData = new LLMsgData(mCurrentRMessageTemplate->mName);
  465. // loop through the template building the data structure as we go
  466. LLMessageTemplate::message_block_map_t::const_iterator iter;
  467. for(iter = mCurrentRMessageTemplate->mMemberBlocks.begin();
  468. iter != mCurrentRMessageTemplate->mMemberBlocks.end();
  469. ++iter)
  470. {
  471. LLMessageBlock* mbci = *iter;
  472. U8 repeat_number;
  473. S32 i;
  474. // how many of this block?
  475. if (mbci->mType == MBT_SINGLE)
  476. {
  477. // just one
  478. repeat_number = 1;
  479. }
  480. else if (mbci->mType == MBT_MULTIPLE)
  481. {
  482. // a known number
  483. repeat_number = mbci->mNumber;
  484. }
  485. else if (mbci->mType == MBT_VARIABLE)
  486. {
  487. // need to read the number from the message
  488. // repeat number is a single byte
  489. if (decode_pos >= mReceiveSize)
  490. {
  491. // commented out - hetgrid says that missing variable blocks
  492. // at end of message are legal
  493. // logRanOffEndOfPacket(sender, decode_pos, 1);
  494. // default to 0 repeats
  495. repeat_number = 0;
  496. }
  497. else
  498. {
  499. repeat_number = buffer[decode_pos];
  500. decode_pos++;
  501. }
  502. }
  503. else
  504. {
  505. llerrs << "Unknown block type" << llendl;
  506. return FALSE;
  507. }
  508. LLMsgBlkData* cur_data_block = NULL;
  509. // now loop through the block
  510. for (i = 0; i < repeat_number; i++)
  511. {
  512. if (i)
  513. {
  514. // build new name to prevent collisions
  515. // TODO: This should really change to a vector
  516. cur_data_block = new LLMsgBlkData(mbci->mName, repeat_number);
  517. cur_data_block->mName = mbci->mName + i;
  518. }
  519. else
  520. {
  521. cur_data_block = new LLMsgBlkData(mbci->mName, repeat_number);
  522. }
  523. // add the block to the message
  524. mCurrentRMessageData->addBlock(cur_data_block);
  525. // now read the variables
  526. for (LLMessageBlock::message_variable_map_t::const_iterator iter =
  527. mbci->mMemberVariables.begin();
  528. iter != mbci->mMemberVariables.end(); iter++)
  529. {
  530. const LLMessageVariable& mvci = **iter;
  531. // ok, build out the variables
  532. // add variable block
  533. cur_data_block->addVariable(mvci.getName(), mvci.getType());
  534. // what type of variable?
  535. if (mvci.getType() == MVT_VARIABLE)
  536. {
  537. // variable, get the number of bytes to read from the template
  538. S32 data_size = mvci.getSize();
  539. U8 tsizeb = 0;
  540. U16 tsizeh = 0;
  541. U32 tsize = 0;
  542. if ((decode_pos + data_size) > mReceiveSize)
  543. {
  544. logRanOffEndOfPacket(sender, decode_pos, data_size);
  545. // default to 0 length variable blocks
  546. tsize = 0;
  547. }
  548. else
  549. {
  550. switch(data_size)
  551. {
  552. case 1:
  553. htonmemcpy(&tsizeb, &buffer[decode_pos], MVT_U8, 1);
  554. tsize = tsizeb;
  555. break;
  556. case 2:
  557. htonmemcpy(&tsizeh, &buffer[decode_pos], MVT_U16, 2);
  558. tsize = tsizeh;
  559. break;
  560. case 4:
  561. htonmemcpy(&tsize, &buffer[decode_pos], MVT_U32, 4);
  562. break;
  563. default:
  564. llerrs << "Attempting to read variable field with unknown size of " << data_size << llendl;
  565. break;
  566. }
  567. }
  568. decode_pos += data_size;
  569. cur_data_block->addData(mvci.getName(), &buffer[decode_pos], tsize, mvci.getType());
  570. decode_pos += tsize;
  571. }
  572. else
  573. {
  574. // fixed!
  575. // so, copy data pointer and set data size to fixed size
  576. if ((decode_pos + mvci.getSize()) > mReceiveSize)
  577. {
  578. logRanOffEndOfPacket(sender, decode_pos, mvci.getSize());
  579. // default to 0s.
  580. U32 size = mvci.getSize();
  581. std::vector<U8> data(size, 0);
  582. cur_data_block->addData(mvci.getName(), &(data[0]),
  583. size, mvci.getType());
  584. }
  585. else
  586. {
  587. cur_data_block->addData(mvci.getName(),
  588. &buffer[decode_pos],
  589. mvci.getSize(),
  590. mvci.getType());
  591. }
  592. decode_pos += mvci.getSize();
  593. }
  594. }
  595. }
  596. }
  597. if (mCurrentRMessageData->mMemberBlocks.empty()
  598. && !mCurrentRMessageTemplate->mMemberBlocks.empty())
  599. {
  600. lldebugs << "Empty message '" << mCurrentRMessageTemplate->mName << "' (no blocks)" << llendl;
  601. return FALSE;
  602. }
  603. {
  604. static LLTimer decode_timer;
  605. if(LLMessageReader::getTimeDecodes() || gMessageSystem->getTimingCallback())
  606. {
  607. decode_timer.reset();
  608. }
  609. {
  610. LLFastTimer t(FTM_PROCESS_MESSAGES);
  611. if( !mCurrentRMessageTemplate->callHandlerFunc(gMessageSystem) )
  612. {
  613. llwarns << "Message from " << sender << " with no handler function received: " << mCurrentRMessageTemplate->mName << llendl;
  614. }
  615. }
  616. if(LLMessageReader::getTimeDecodes() || gMessageSystem->getTimingCallback())
  617. {
  618. F32 decode_time = decode_timer.getElapsedTimeF32();
  619. if (gMessageSystem->getTimingCallback())
  620. {
  621. (gMessageSystem->getTimingCallback())(mCurrentRMessageTemplate->mName,
  622. decode_time,
  623. gMessageSystem->getTimingCallbackData());
  624. }
  625. if (LLMessageReader::getTimeDecodes())
  626. {
  627. mCurrentRMessageTemplate->mDecodeTimeThisFrame += decode_time;
  628. mCurrentRMessageTemplate->mTotalDecoded++;
  629. mCurrentRMessageTemplate->mTotalDecodeTime += decode_time;
  630. if( mCurrentRMessageTemplate->mMaxDecodeTimePerMsg < decode_time )
  631. {
  632. mCurrentRMessageTemplate->mMaxDecodeTimePerMsg = decode_time;
  633. }
  634. if(decode_time > LLMessageReader::getTimeDecodesSpamThreshold())
  635. {
  636. lldebugs << "--------- Message " << mCurrentRMessageTemplate->mName << " decode took " << decode_time << " seconds. (" <<
  637. mCurrentRMessageTemplate->mMaxDecodeTimePerMsg << " max, " <<
  638. (mCurrentRMessageTemplate->mTotalDecodeTime / mCurrentRMessageTemplate->mTotalDecoded) << " avg)" << llendl;
  639. }
  640. }
  641. }
  642. }
  643. return TRUE;
  644. }
  645. BOOL LLTemplateMessageReader::validateMessage(const U8* buffer,
  646. S32 buffer_size,
  647. const LLHost& sender,
  648. bool trusted)
  649. {
  650. mReceiveSize = buffer_size;
  651. BOOL valid = decodeTemplate(buffer, buffer_size, &mCurrentRMessageTemplate );
  652. if(valid)
  653. {
  654. mCurrentRMessageTemplate->mReceiveCount++;
  655. //lldebugs << "MessageRecvd:"
  656. // << mCurrentRMessageTemplate->mName
  657. // << " from " << sender << llendl;
  658. }
  659. if (valid && isBanned(trusted))
  660. {
  661. LL_WARNS("Messaging") << "LLMessageSystem::checkMessages "
  662. << "received banned message "
  663. << getMessageName()
  664. << " from "
  665. << ((trusted) ? "trusted " : "untrusted ")
  666. << sender << llendl;
  667. valid = FALSE;
  668. }
  669. if(valid && isUdpBanned())
  670. {
  671. llwarns << "Received UDP black listed message "
  672. << getMessageName()
  673. << " from " << sender << llendl;
  674. valid = FALSE;
  675. }
  676. return valid;
  677. }
  678. BOOL LLTemplateMessageReader::readMessage(const U8* buffer,
  679. const LLHost& sender)
  680. {
  681. return decodeData(buffer, sender);
  682. }
  683. //virtual
  684. const char* LLTemplateMessageReader::getMessageName() const
  685. {
  686. if (!mCurrentRMessageTemplate)
  687. {
  688. // no message currently being read
  689. return "";
  690. }
  691. return mCurrentRMessageTemplate->mName;
  692. }
  693. //virtual
  694. bool LLTemplateMessageReader::isTrusted() const
  695. {
  696. return mCurrentRMessageTemplate->getTrust() == MT_TRUST;
  697. }
  698. bool LLTemplateMessageReader::isBanned(bool trustedSource) const
  699. {
  700. return mCurrentRMessageTemplate->isBanned(trustedSource);
  701. }
  702. bool LLTemplateMessageReader::isUdpBanned() const
  703. {
  704. return mCurrentRMessageTemplate->isUdpBanned();
  705. }
  706. //virtual
  707. void LLTemplateMessageReader::copyToBuilder(LLMessageBuilder& builder) const
  708. {
  709. if(NULL == mCurrentRMessageTemplate)
  710. {
  711. return;
  712. }
  713. builder.copyFromMessageData(*mCurrentRMessageData);
  714. }