lltemplatemessagereader.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913
  1. /**
  2. * @file lltemplatemessagereader.cpp
  3. * @brief LLTemplateMessageReader class implementation.
  4. *
  5. * $LicenseInfo:firstyear=2007&license=viewergpl$
  6. *
  7. * Copyright (c) 2007-2009, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #include "linden_common.h"
  33. #include "lltemplatemessagereader.h"
  34. #include "llfasttimer.h"
  35. #include "llmessagebuilder.h"
  36. #include "llmessagetemplate.h"
  37. #include "llmath.h"
  38. #include "llquaternion.h"
  39. #include "llmessage.h"
  40. #include "llvector3d.h"
  41. #include "llvector3.h"
  42. #include "llvector4.h"
  43. LLTemplateMessageReader::LLTemplateMessageReader(template_number_map_t& number_template_map)
  44. : mReceiveSize(0),
  45. mCurrentRMessageTemplate(NULL),
  46. mCurrentRMessageData(NULL),
  47. mMessageNumbers(number_template_map)
  48. {
  49. }
  50. //virtual
  51. LLTemplateMessageReader::~LLTemplateMessageReader()
  52. {
  53. delete mCurrentRMessageData;
  54. mCurrentRMessageData = NULL;
  55. }
  56. //virtual
  57. void LLTemplateMessageReader::clearMessage()
  58. {
  59. mReceiveSize = -1;
  60. mCurrentRMessageTemplate = NULL;
  61. delete mCurrentRMessageData;
  62. mCurrentRMessageData = NULL;
  63. }
  64. void LLTemplateMessageReader::getData(const char* blockname,
  65. const char* varname,
  66. void* datap, S32 size,
  67. S32 blocknum, S32 max_size)
  68. {
  69. // Is there a message ready to go ?
  70. if (mReceiveSize == -1)
  71. {
  72. llwarns << "No message waiting for decode 2. Ignoring." << llendl;
  73. llassert(false);
  74. memset(datap, 0, size);
  75. return;
  76. }
  77. if (!mCurrentRMessageData)
  78. {
  79. llerrs << "Invalid mCurrentMessageData in getData !" << llendl;
  80. }
  81. // This works because it is just a hash. The bnamep is never dereferenced:
  82. char* bnamep = (char*)blockname + blocknum;
  83. char* vnamep = (char*)varname;
  84. LLMsgData::msg_blk_data_map_t::const_iterator iter =
  85. mCurrentRMessageData->mMemberBlocks.find(bnamep);
  86. if (iter == mCurrentRMessageData->mMemberBlocks.end())
  87. {
  88. llwarns << "Block " << blockname << " #" << blocknum
  89. << " not in message " << mCurrentRMessageData->mName
  90. << ". Ignoring." << llendl;
  91. llassert(false);
  92. memset(datap, 0, size);
  93. return;
  94. }
  95. LLMsgBlkData* msg_block_data = iter->second;
  96. LLMsgBlkData::msg_var_data_map_t& var_data_map =
  97. msg_block_data->mMemberVarData;
  98. if (var_data_map.find(vnamep) == var_data_map.end())
  99. {
  100. llwarns << "Variable "<< vnamep << " not in message "
  101. << mCurrentRMessageData->mName << " block " << bnamep
  102. << ". Ignoring." << llendl;
  103. llassert(false);
  104. memset(datap, 0, size);
  105. return;
  106. }
  107. LLMsgVarData& vardata = msg_block_data->mMemberVarData[vnamep];
  108. const S32 vardata_size = vardata.getSize();
  109. // Yes, it may happen (seen once) !!! HB
  110. if (vardata_size < 0)
  111. {
  112. llwarns << "Variable "<< vnamep << " size is negative: "
  113. << vardata_size<< " block " << bnamep
  114. << ". Ignoring." << llendl;
  115. llassert(false);
  116. memset(datap, 0, size);
  117. return;
  118. }
  119. if (size && size != vardata_size)
  120. {
  121. if (size > vardata_size)
  122. {
  123. llwarns << "Msg " << mCurrentRMessageData->mName << " variable "
  124. << vnamep << " is size " << vardata_size
  125. << " but copying into buffer of size " << size
  126. << ". Proceeding anyway..." << llendl;
  127. llassert(false);
  128. // Zero the data first, since it will not fully be filled up
  129. memset(datap, 0, size);
  130. }
  131. else
  132. {
  133. llerrs << "Msg " << mCurrentRMessageData->mName << " variable "
  134. << vnamep << " is size " << vardata_size
  135. << " but copying into buffer of size " << size << llendl;
  136. }
  137. }
  138. if (max_size >= vardata_size)
  139. {
  140. switch (vardata_size)
  141. {
  142. case 1:
  143. *((U8*)datap) = *((U8*)vardata.getData());
  144. break;
  145. case 2:
  146. *((U16*)datap) = *((U16*)vardata.getData());
  147. break;
  148. case 4:
  149. *((U32*)datap) = *((U32*)vardata.getData());
  150. break;
  151. case 8:
  152. ((U32*)datap)[0] = ((U32*)vardata.getData())[0];
  153. ((U32*)datap)[1] = ((U32*)vardata.getData())[1];
  154. break;
  155. default:
  156. memcpy(datap, vardata.getData(), vardata_size);
  157. }
  158. }
  159. else
  160. {
  161. llwarns << "Msg " << mCurrentRMessageData->mName << " variable "
  162. << vnamep << " is size " << vardata.getSize()
  163. << " but truncated to max size of " << max_size << llendl;
  164. memcpy(datap, vardata.getData(), max_size);
  165. }
  166. }
  167. S32 LLTemplateMessageReader::getNumberOfBlocks(const char* blockname)
  168. {
  169. // Is there a message ready to go ?
  170. if (mReceiveSize == -1)
  171. {
  172. llwarns << "No message waiting for decode 3. Ignoring." << llendl;
  173. llassert(false);
  174. return 0;
  175. }
  176. if (!mCurrentRMessageData)
  177. {
  178. llerrs << "Invalid mCurrentRMessageData in getData !" << llendl;
  179. }
  180. char* bnamep = (char*)blockname;
  181. LLMsgData::msg_blk_data_map_t::const_iterator iter;
  182. iter = mCurrentRMessageData->mMemberBlocks.find(bnamep);
  183. if (iter == mCurrentRMessageData->mMemberBlocks.end())
  184. {
  185. return 0;
  186. }
  187. return (iter->second)->mBlockNumber;
  188. }
  189. S32 LLTemplateMessageReader::getSize(const char* blockname,
  190. const char* varname)
  191. {
  192. // Is there a message ready to go ?
  193. if (mReceiveSize == -1)
  194. {
  195. llwarns << "No message waiting for decode 4. Ignoring." << llendl;
  196. llassert(false);
  197. return LL_MESSAGE_ERROR;
  198. }
  199. if (!mCurrentRMessageData)
  200. {
  201. // This is a serious error - crash
  202. llerrs << "Invalid mCurrentRMessageData in getData !" << llendl;
  203. }
  204. char* bnamep = (char*)blockname;
  205. LLMsgData::msg_blk_data_map_t::const_iterator iter;
  206. iter = mCurrentRMessageData->mMemberBlocks.find(bnamep);
  207. if (iter == mCurrentRMessageData->mMemberBlocks.end())
  208. {
  209. // Do not crash
  210. llinfos << "Block " << bnamep << " not in message "
  211. << mCurrentRMessageData->mName << llendl;
  212. return LL_BLOCK_NOT_IN_MESSAGE;
  213. }
  214. char* vnamep = (char*)varname;
  215. LLMsgBlkData* msg_data = iter->second;
  216. LLMsgVarData& vardata = msg_data->mMemberVarData[vnamep];
  217. if (!vardata.getName())
  218. {
  219. // Do not crash
  220. llinfos << "Variable " << varname << " not in message "
  221. << mCurrentRMessageData->mName << " block " << bnamep
  222. << llendl;
  223. return LL_VARIABLE_NOT_IN_BLOCK;
  224. }
  225. if (mCurrentRMessageTemplate->mMemberBlocks[bnamep]->mType != MBT_SINGLE)
  226. {
  227. // This is a serious error - crash
  228. llerrs << "Block " << bnamep
  229. << " is not of type MBT_SINGLE, use getSize with blocknum argument !"
  230. << llendl;
  231. }
  232. return vardata.getSize();
  233. }
  234. S32 LLTemplateMessageReader::getSize(const char* blockname, S32 blocknum,
  235. const char* varname)
  236. {
  237. // Is there a message ready to go ?
  238. if (mReceiveSize == -1)
  239. {
  240. llwarns << "No message waiting for decode 5. Ignoring." << llendl;
  241. llassert(false);
  242. return LL_MESSAGE_ERROR;
  243. }
  244. if (!mCurrentRMessageData)
  245. {
  246. // This is a serious error - crash
  247. llerrs << "Invalid mCurrentRMessageData in getData !" << llendl;
  248. }
  249. char* bnamep = (char*)blockname + blocknum;
  250. char* vnamep = (char*)varname;
  251. LLMsgData::msg_blk_data_map_t::const_iterator iter;
  252. iter = mCurrentRMessageData->mMemberBlocks.find(bnamep);
  253. if (iter == mCurrentRMessageData->mMemberBlocks.end())
  254. {
  255. // Do not crash
  256. llinfos << "Block " << bnamep << " not in message "
  257. << mCurrentRMessageData->mName << llendl;
  258. return LL_BLOCK_NOT_IN_MESSAGE;
  259. }
  260. LLMsgBlkData* msg_data = iter->second;
  261. LLMsgVarData& vardata = msg_data->mMemberVarData[vnamep];
  262. if (!vardata.getName())
  263. {
  264. // Do not crash
  265. llinfos << "Variable " << vnamep << " not in message "
  266. << mCurrentRMessageData->mName << " block " << bnamep
  267. << llendl;
  268. return LL_VARIABLE_NOT_IN_BLOCK;
  269. }
  270. return vardata.getSize();
  271. }
  272. void LLTemplateMessageReader::getBinaryData(const char* blockname,
  273. const char* varname, void* datap,
  274. S32 size, S32 blocknum,
  275. S32 max_size)
  276. {
  277. getData(blockname, varname, datap, size, blocknum, max_size);
  278. }
  279. void LLTemplateMessageReader::getS8(const char* block, const char* var,
  280. S8& u, S32 blocknum)
  281. {
  282. getData(block, var, &u, sizeof(S8), blocknum);
  283. }
  284. void LLTemplateMessageReader::getU8(const char* block, const char* var,
  285. U8& u, S32 blocknum)
  286. {
  287. getData(block, var, &u, sizeof(U8), blocknum);
  288. }
  289. void LLTemplateMessageReader::getBool(const char* block, const char* var,
  290. bool& b, S32 blocknum)
  291. {
  292. U8 value = 0;
  293. getData(block, var, &value, sizeof(U8), blocknum);
  294. b = value != 0;
  295. }
  296. void LLTemplateMessageReader::getS16(const char* block, const char* var,
  297. S16& d, S32 blocknum)
  298. {
  299. getData(block, var, &d, sizeof(S16), blocknum);
  300. }
  301. void LLTemplateMessageReader::getU16(const char* block, const char* var,
  302. U16& d, S32 blocknum)
  303. {
  304. getData(block, var, &d, sizeof(U16), blocknum);
  305. }
  306. void LLTemplateMessageReader::getS32(const char* block, const char* var,
  307. S32& d, S32 blocknum)
  308. {
  309. getData(block, var, &d, sizeof(S32), blocknum);
  310. }
  311. void LLTemplateMessageReader::getU32(const char* block, const char* var,
  312. U32& d, S32 blocknum)
  313. {
  314. getData(block, var, &d, sizeof(U32), blocknum);
  315. }
  316. void LLTemplateMessageReader::getU64(const char* block, const char* var,
  317. U64& d, S32 blocknum)
  318. {
  319. getData(block, var, &d, sizeof(U64), blocknum);
  320. }
  321. void LLTemplateMessageReader::getF32(const char* block, const char* var,
  322. F32& d, S32 blocknum)
  323. {
  324. getData(block, var, &d, sizeof(F32), blocknum);
  325. if (!llfinite(d))
  326. {
  327. llwarns << "non-finite in getF32Fast " << block << " " << var
  328. << llendl;
  329. d = 0;
  330. }
  331. }
  332. void LLTemplateMessageReader::getF64(const char* block, const char* var,
  333. F64& d, S32 blocknum)
  334. {
  335. getData(block, var, &d, sizeof(F64), blocknum);
  336. if (!llfinite(d))
  337. {
  338. llwarns << "non-finite in getF64Fast " << block << " " << var
  339. << llendl;
  340. d = 0;
  341. }
  342. }
  343. void LLTemplateMessageReader::getVector3(const char* block, const char* var,
  344. LLVector3& v, S32 blocknum)
  345. {
  346. getData(block, var, &v.mV[0], sizeof(v.mV), blocknum);
  347. if (!v.isFinite())
  348. {
  349. llwarns << "non-finite in getVector3Fast " << block << " "
  350. << var << llendl;
  351. v.setZero();
  352. }
  353. }
  354. void LLTemplateMessageReader::getVector4(const char* block, const char* var,
  355. LLVector4& v, S32 blocknum)
  356. {
  357. getData(block, var, &v.mV[0], sizeof(v.mV), blocknum);
  358. if (!v.isFinite())
  359. {
  360. llwarns << "non-finite in getVector4Fast " << block << " "
  361. << var << llendl;
  362. v.setZero();
  363. }
  364. }
  365. void LLTemplateMessageReader::getVector3d(const char* block, const char* var,
  366. LLVector3d& v, S32 blocknum)
  367. {
  368. getData(block, var, &v.mdV[0], sizeof(v.mdV), blocknum);
  369. if (!v.isFinite())
  370. {
  371. llwarns << "non-finite in getVector3dFast " << block << " "
  372. << var << llendl;
  373. v.setZero();
  374. }
  375. }
  376. void LLTemplateMessageReader::getQuat(const char* block, const char* var,
  377. LLQuaternion& q, S32 blocknum)
  378. {
  379. LLVector3 vec;
  380. getData(block, var, &vec.mV[0], sizeof(vec.mV), blocknum);
  381. if (vec.isFinite())
  382. {
  383. q.unpackFromVector3(vec);
  384. }
  385. else
  386. {
  387. llwarns << "non-finite in getQuatFast " << block << " " << var
  388. << llendl;
  389. q.loadIdentity();
  390. }
  391. }
  392. void LLTemplateMessageReader::getUUID(const char* block, const char* var,
  393. LLUUID& u, S32 blocknum)
  394. {
  395. getData(block, var, &u.mData[0], sizeof(u.mData), blocknum);
  396. }
  397. LL_INLINE void LLTemplateMessageReader::getIPAddr(const char* block,
  398. const char* var,
  399. U32& u, S32 blocknum)
  400. {
  401. getData(block, var, &u, sizeof(U32), blocknum);
  402. }
  403. LL_INLINE void LLTemplateMessageReader::getIPPort(const char* block,
  404. const char* var,
  405. U16& u, S32 blocknum)
  406. {
  407. getData(block, var, &u, sizeof(U16), blocknum);
  408. u = ntohs(u);
  409. }
  410. LL_INLINE void LLTemplateMessageReader::getString(const char* block,
  411. const char* var,
  412. S32 buffer_size,
  413. char* s, S32 blocknum)
  414. {
  415. s[0] = '\0';
  416. getData(block, var, s, 0, blocknum, buffer_size);
  417. s[buffer_size - 1] = '\0';
  418. }
  419. LL_INLINE void LLTemplateMessageReader::getString(const char* block,
  420. const char* var,
  421. std::string& outstr,
  422. S32 blocknum)
  423. {
  424. char s[MTUBYTES + 1]= { 0 }; // every element is initialized with 0
  425. getData(block, var, s, 0, blocknum, MTUBYTES);
  426. s[MTUBYTES] = '\0';
  427. outstr = s;
  428. }
  429. //virtual
  430. S32 LLTemplateMessageReader::getMessageSize() const
  431. {
  432. return mReceiveSize;
  433. }
  434. // Returns template for the message contained in buffer
  435. // buffer = inputs, msg_template = outputs
  436. bool LLTemplateMessageReader::decodeTemplate(const U8* buffer, S32 buffer_size,
  437. LLMessageTemplate** msg_template)
  438. {
  439. if (!buffer)
  440. {
  441. llwarns << "NULL buffer !" << llendl;
  442. llassert(false);
  443. return false;
  444. }
  445. const U8* header = buffer + LL_PACKET_ID_SIZE;
  446. // Is there a message ready to go ?
  447. if (buffer_size <= 0)
  448. {
  449. llwarns << "No message waiting for decode !" << llendl;
  450. return false;
  451. }
  452. U32 num = 0;
  453. if (header[0] != 255)
  454. {
  455. // High frequency message
  456. num = header[0];
  457. }
  458. else if (buffer_size >= (S32)LL_MINIMUM_VALID_PACKET_SIZE + 1 &&
  459. header[1] != 255)
  460. {
  461. // Medium frequency message
  462. num = (255 << 8) | header[1];
  463. }
  464. else if (buffer_size >= (S32)LL_MINIMUM_VALID_PACKET_SIZE + 3 &&
  465. header[1] == 255)
  466. {
  467. // Low frequency message
  468. U16 message_id_U16 = 0;
  469. #if 0 // I think this check busts the message system. It appears that if
  470. // there is a NULL in the message #, it would not copy it.... What was
  471. // the goal ?
  472. if (header[2])
  473. #endif
  474. memcpy(&message_id_U16, &header[2], 2);
  475. // Independant of endian-ness:
  476. message_id_U16 = ntohs(message_id_U16);
  477. num = 0xFFFF0000 | message_id_U16;
  478. }
  479. else // Bogus packet received (too short)
  480. {
  481. llwarns << "Packet with unusable length received (too short): "
  482. << buffer_size << llendl;
  483. return false;
  484. }
  485. LLMessageTemplate* temp = get_ptr_in_map(mMessageNumbers, num);
  486. if (temp)
  487. {
  488. *msg_template = temp;
  489. }
  490. else
  491. {
  492. llwarns_once << "Message #" << std::hex << num << std::dec
  493. << " received but not registered !" << llendl;
  494. #if 0 // MAINT-7482: make viewer tolerant to unknown messages.
  495. gMessageSystemp->callExceptionFunc(MX_UNREGISTERED_MESSAGE);
  496. #endif
  497. return false;
  498. }
  499. return true;
  500. }
  501. void LLTemplateMessageReader::logRanOffEndOfPacket(const LLHost& host,
  502. S32 where, S32 wanted)
  503. {
  504. // We have run off the end of the packet !
  505. llwarns << "Ran off end of packet " << mCurrentRMessageTemplate->mName
  506. #if 0
  507. << " with id " << mCurrentRecvPacketID
  508. #endif
  509. << " from " << host << " trying to read " << wanted
  510. << " bytes at position " << where << " going past packet end at "
  511. << mReceiveSize << llendl;
  512. if (gMessageSystemp->mVerboseLog)
  513. {
  514. llwarns << "MSG: -> " << host << "\tREAD PAST END:\t"
  515. #if 0
  516. << mCurrentRecvPacketID << " "
  517. #endif
  518. << getMessageName() << llendl;
  519. }
  520. gMessageSystemp->callExceptionFunc(MX_RAN_OFF_END_OF_PACKET);
  521. }
  522. // Decode a given message
  523. bool LLTemplateMessageReader::decodeData(const U8* buffer,
  524. const LLHost& sender)
  525. {
  526. llassert(mReceiveSize >= 0 && mCurrentRMessageTemplate &&
  527. !mCurrentRMessageData);
  528. delete mCurrentRMessageData; // Just to make sure
  529. // The offset tells us how may bytes to skip after the end of the
  530. // message name.
  531. U8 offset = buffer[PHL_OFFSET];
  532. S32 decode_pos = LL_PACKET_ID_SIZE +
  533. (S32)(mCurrentRMessageTemplate->mFrequency) + offset;
  534. // Create base working data set
  535. mCurrentRMessageData = new LLMsgData(mCurrentRMessageTemplate->mName);
  536. // Loop through the template building the data structure as we go
  537. LLMessageTemplate::message_block_map_t::const_iterator iter;
  538. for (iter = mCurrentRMessageTemplate->mMemberBlocks.begin();
  539. iter != mCurrentRMessageTemplate->mMemberBlocks.end(); ++iter)
  540. {
  541. LLMessageBlock* mbci = *iter;
  542. U8 repeat_number = 0;
  543. S32 i;
  544. // how many of this block?
  545. if (mbci->mType == MBT_SINGLE)
  546. {
  547. // just one
  548. repeat_number = 1;
  549. }
  550. else if (mbci->mType == MBT_MULTIPLE)
  551. {
  552. // A known number
  553. repeat_number = mbci->mNumber;
  554. }
  555. else if (mbci->mType == MBT_VARIABLE)
  556. {
  557. // Need to read the number from the message: repeat number is a
  558. // single byte
  559. if (decode_pos >= mReceiveSize)
  560. {
  561. #if 0 // Hetgrid says that missing variable blocks at end of message
  562. // are legal
  563. logRanOffEndOfPacket(sender, decode_pos, 1);
  564. #endif
  565. // Default to 0 repeats
  566. repeat_number = 0;
  567. }
  568. else
  569. {
  570. repeat_number = buffer[decode_pos++];
  571. }
  572. }
  573. else
  574. {
  575. llerrs << "Unknown block type !" << llendl;
  576. }
  577. LLMsgBlkData* cur_data_block = NULL;
  578. // Now loop through the block
  579. for (i = 0; i < repeat_number; ++i)
  580. {
  581. if (i)
  582. {
  583. // Build new name to prevent collisions.
  584. // *TODO: this should really change to a vector.
  585. cur_data_block = new LLMsgBlkData(mbci->mName, repeat_number);
  586. cur_data_block->mName = mbci->mName + i;
  587. }
  588. else
  589. {
  590. cur_data_block = new LLMsgBlkData(mbci->mName, repeat_number);
  591. }
  592. // Add the block to the message
  593. mCurrentRMessageData->addBlock(cur_data_block);
  594. // Now read the variables
  595. for (LLMessageBlock::message_variable_map_t::const_iterator
  596. iter = mbci->mMemberVariables.begin();
  597. iter != mbci->mMemberVariables.end(); ++iter)
  598. {
  599. const LLMessageVariable& mvci = **iter;
  600. // OK, build out the variables: add a variable block
  601. cur_data_block->addVariable(mvci.getName(), mvci.getType());
  602. // What type of variable ?
  603. if (mvci.getType() == MVT_VARIABLE)
  604. {
  605. // variable, get the number of bytes to read from the template
  606. S32 data_size = mvci.getSize();
  607. U8 tsizeb = 0;
  608. U16 tsizeh = 0;
  609. U32 tsize = 0;
  610. if (decode_pos + data_size > mReceiveSize)
  611. {
  612. logRanOffEndOfPacket(sender, decode_pos, data_size);
  613. // default to 0 length variable blocks
  614. tsize = 0;
  615. }
  616. else
  617. {
  618. switch (data_size)
  619. {
  620. case 1:
  621. htonmemcpy(&tsizeb, &buffer[decode_pos],
  622. MVT_U8, 1);
  623. tsize = tsizeb;
  624. break;
  625. case 2:
  626. htonmemcpy(&tsizeh, &buffer[decode_pos],
  627. MVT_U16, 2);
  628. tsize = tsizeh;
  629. break;
  630. case 4:
  631. htonmemcpy(&tsize, &buffer[decode_pos],
  632. MVT_U32, 4);
  633. break;
  634. default:
  635. llerrs << "Attempting to read variable field with unknown size of "
  636. << data_size << llendl;
  637. }
  638. }
  639. decode_pos += data_size;
  640. cur_data_block->addData(mvci.getName(),
  641. &buffer[decode_pos], tsize,
  642. mvci.getType());
  643. decode_pos += tsize;
  644. }
  645. else
  646. {
  647. // Fixed ! So, copy data pointer and set data size to
  648. // fixed size
  649. if (decode_pos + mvci.getSize() > mReceiveSize)
  650. {
  651. logRanOffEndOfPacket(sender, decode_pos,
  652. mvci.getSize());
  653. // Default to 0s.
  654. U32 size = mvci.getSize();
  655. std::vector<U8> data(size, 0);
  656. cur_data_block->addData(mvci.getName(), data.data(),
  657. size, mvci.getType());
  658. }
  659. else
  660. {
  661. cur_data_block->addData(mvci.getName(),
  662. &buffer[decode_pos],
  663. mvci.getSize(),
  664. mvci.getType());
  665. }
  666. decode_pos += mvci.getSize();
  667. }
  668. }
  669. }
  670. }
  671. if (mCurrentRMessageData->mMemberBlocks.empty() &&
  672. !mCurrentRMessageTemplate->mMemberBlocks.empty())
  673. {
  674. LL_DEBUGS("Messaging") << "Empty message '"
  675. << mCurrentRMessageTemplate->mName
  676. << "' (no blocks)" << LL_ENDL;
  677. return false;
  678. }
  679. static LLTimer decode_timer;
  680. LLMessageSystem* msg = gMessageSystemp;
  681. if (LLMessageReader::getTimeDecodes() || msg->getTimingCallback())
  682. {
  683. decode_timer.reset();
  684. }
  685. const char* msg_name = mCurrentRMessageTemplate->mName;
  686. if (msg_name != _PREHASH_PacketAck)
  687. {
  688. LL_DEBUGS("Messaging") << "Received " << msg_name
  689. << " from host " << sender.getIPandPort()
  690. << LL_ENDL;
  691. }
  692. {
  693. LL_FAST_TIMER(FTM_PROCESS_MESSAGES);
  694. if (!mCurrentRMessageTemplate->callHandlerFunc(msg))
  695. {
  696. llwarns << "Message from " << sender
  697. << " with no handler function received: " << msg_name
  698. << llendl;
  699. }
  700. }
  701. if (LLMessageReader::getTimeDecodes() || msg->getTimingCallback())
  702. {
  703. F32 decode_time = decode_timer.getElapsedTimeF32();
  704. if (msg->getTimingCallback())
  705. {
  706. (msg->getTimingCallback())(msg_name, decode_time,
  707. msg->getTimingCallbackData());
  708. }
  709. if (LLMessageReader::getTimeDecodes())
  710. {
  711. mCurrentRMessageTemplate->mDecodeTimeThisFrame += decode_time;
  712. ++mCurrentRMessageTemplate->mTotalDecoded;
  713. mCurrentRMessageTemplate->mTotalDecodeTime += decode_time;
  714. if (mCurrentRMessageTemplate->mMaxDecodeTimePerMsg < decode_time)
  715. {
  716. mCurrentRMessageTemplate->mMaxDecodeTimePerMsg = decode_time;
  717. }
  718. if (decode_time > LLMessageReader::getTimeDecodesSpamThreshold())
  719. {
  720. LL_DEBUGS("Messaging") << "--------- Message "
  721. << msg_name
  722. << " decode took " << decode_time
  723. << " seconds. ("
  724. << mCurrentRMessageTemplate->mMaxDecodeTimePerMsg
  725. << " max, "
  726. << (mCurrentRMessageTemplate->mTotalDecodeTime /
  727. mCurrentRMessageTemplate->mTotalDecoded)
  728. << " avg)" << LL_ENDL;
  729. }
  730. }
  731. }
  732. return true;
  733. }
  734. bool LLTemplateMessageReader::validateMessage(const U8* buffer,
  735. S32 buffer_size,
  736. const LLHost& sender,
  737. bool trusted)
  738. {
  739. mReceiveSize = buffer_size;
  740. bool valid = decodeTemplate(buffer, buffer_size, &mCurrentRMessageTemplate);
  741. if (valid)
  742. {
  743. ++mCurrentRMessageTemplate->mReceiveCount;
  744. }
  745. if (valid && isBanned(trusted))
  746. {
  747. llwarns << "Received banned message " << getMessageName() << " from "
  748. << (trusted ? "trusted " : "untrusted ") << sender << llendl;
  749. return false;
  750. }
  751. if (valid && isUdpBanned())
  752. {
  753. llwarns << "Received UDP black listed message "
  754. << getMessageName()
  755. << " from " << sender << llendl;
  756. return false;
  757. }
  758. return valid;
  759. }
  760. bool LLTemplateMessageReader::readMessage(const U8* buffer,
  761. const LLHost& sender)
  762. {
  763. return decodeData(buffer, sender);
  764. }
  765. //virtual
  766. const char* LLTemplateMessageReader::getMessageName() const
  767. {
  768. if (!mCurrentRMessageTemplate)
  769. {
  770. // no message currently being read
  771. return "";
  772. }
  773. return mCurrentRMessageTemplate->mName;
  774. }
  775. //virtual
  776. bool LLTemplateMessageReader::isTrusted() const
  777. {
  778. return mCurrentRMessageTemplate->getTrust() == MT_TRUST;
  779. }
  780. bool LLTemplateMessageReader::isBanned(bool trustedSource) const
  781. {
  782. return mCurrentRMessageTemplate->isBanned(trustedSource);
  783. }
  784. bool LLTemplateMessageReader::isUdpBanned() const
  785. {
  786. return mCurrentRMessageTemplate->isUdpBanned();
  787. }
  788. //virtual
  789. void LLTemplateMessageReader::copyToBuilder(LLMessageBuilder& builder) const
  790. {
  791. if (!mCurrentRMessageTemplate)
  792. {
  793. return;
  794. }
  795. builder.copyFromMessageData(*mCurrentRMessageData);
  796. }