llmessage.h 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179
  1. /**
  2. * @file llmessage.h
  3. * @brief LLMessageSystem class header file
  4. *
  5. * $LicenseInfo:firstyear=2001&license=viewergpl$
  6. *
  7. * Copyright (c) 2001-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. #ifndef LL_MESSAGE_H
  33. #define LL_MESSAGE_H
  34. #include <cstring>
  35. #include <map>
  36. #include <memory>
  37. #include <set>
  38. #include <utility>
  39. #include "boost/function.hpp"
  40. #if LL_LINUX
  41. # include <endian.h>
  42. # include <netinet/in.h>
  43. #endif
  44. #if LL_WINDOWS
  45. # include "winsock2.h" // For htons etc.
  46. #endif
  47. #include "llcircuit.h"
  48. #include "llerror.h"
  49. #include "hbfastmap.h"
  50. #include "llhost.h"
  51. #include "llhttpnode.h"
  52. #include "llcorehttpoptions.h"
  53. #include "llsd.h"
  54. #include "llmessagebuilder.h"
  55. #include "llmutex.h" // For LL_USE_FIBER_AWARE_MUTEX
  56. #include "llpacketack.h"
  57. #include "llpacketring.h"
  58. #include "llstl.h"
  59. #include "llstringtable.h"
  60. #include "lltimer.h"
  61. #include "message_prehash.h"
  62. constexpr U32 MESSAGE_MAX_STRINGS_LENGTH = 64;
  63. constexpr U32 MESSAGE_NUMBER_OF_HASH_BUCKETS = 8192;
  64. constexpr S32 MESSAGE_MAX_PER_FRAME = 500;
  65. class LLMessageStringTable
  66. {
  67. protected:
  68. LOG_CLASS(LLMessageStringTable);
  69. public:
  70. LLMessageStringTable();
  71. char* getString(const char* str);
  72. public:
  73. U32 mUsed;
  74. bool mEmpty[MESSAGE_NUMBER_OF_HASH_BUCKETS];
  75. char mString[MESSAGE_NUMBER_OF_HASH_BUCKETS][MESSAGE_MAX_STRINGS_LENGTH];
  76. };
  77. extern LLMessageStringTable gMessageStringTable;
  78. // Individual Messages are described with the following format
  79. // Note that to ease parsing, keywords are used
  80. //
  81. // // Comment (Comment like a C++ single line comment)
  82. // Comments can only be placed between Messages
  83. // {
  84. // MessageName (same naming restrictions as C variable)
  85. // Frequency ("High", "Medium", or "Low" - determines whether message ID is 8, 16, or 32-bits --
  86. // there can 254 messages in the first 2 groups, 32K in the last group)
  87. // (A message can be made up only of the Name if it is only a signal)
  88. // Trust ("Trusted", "NotTrusted" - determines if a message will be accepted
  89. // on a circuit. "Trusted" messages are not accepted from NotTrusted circuits
  90. // while NotTrusted messages are accepted on any circuit. An example of a
  91. // NotTrusted circuit is any circuit from the viewer.)
  92. // Encoding ("Zerocoded", "Unencoded" - zerocoded messages attempt to compress sequences of
  93. // zeros, but if there is no space win, it discards the compression and goes unencoded)
  94. // {
  95. // Block Name (same naming restrictions as C variable)
  96. // Block Type ("Single", "Multiple", or "Variable" - determines if the block is coded once,
  97. // a known number of times, or has a 8 bit argument encoded to tell the decoder
  98. // how many times the group is repeated)
  99. // Block Repeat Number (Optional - used only with the "Multiple" type - tells how many times the field is repeated
  100. // {
  101. // Variable 1 Name (same naming restrictions as C variable)
  102. // Variable Type ("Fixed" or "Variable" - determines if the variable is of fixed size or needs to
  103. // encode an argument describing the size in bytes)
  104. // Variable Size (In bytes, either of the "Fixed" variable itself or of the size argument)
  105. //
  106. // repeat variables
  107. //
  108. // }
  109. //
  110. // Repeat for number of variables in block
  111. // }
  112. //
  113. // Repeat for number of blocks in message
  114. // }
  115. // Repeat for number of messages in file
  116. //
  117. // Constants
  118. constexpr S32 MAX_MESSAGE_INTERNAL_NAME_SIZE = 255;
  119. constexpr S32 MAX_BUFFER_SIZE = NET_BUFFER_SIZE;
  120. constexpr S32 MAX_BLOCKS = 255;
  121. constexpr U8 LL_ZERO_CODE_FLAG = 0x80;
  122. constexpr U8 LL_RELIABLE_FLAG = 0x40;
  123. constexpr U8 LL_RESENT_FLAG = 0x20;
  124. constexpr U8 LL_ACK_FLAG = 0x10;
  125. // 1 byte flags, 4 bytes sequence, 1 byte offset + 1 byte message name (high)
  126. constexpr S32 LL_MINIMUM_VALID_PACKET_SIZE = LL_PACKET_ID_SIZE + 1;
  127. enum EPacketHeaderLayout
  128. {
  129. PHL_FLAGS = 0,
  130. PHL_PACKET_ID = 1,
  131. PHL_OFFSET = 5,
  132. PHL_NAME = 6
  133. };
  134. constexpr U32 LL_DEFAULT_RELIABLE_RETRIES = 3;
  135. constexpr F32 LL_MINIMUM_RELIABLE_TIMEOUT_SECONDS = 1.f;
  136. constexpr F32 LL_MINIMUM_SEMIRELIABLE_TIMEOUT_SECONDS = 1.f;
  137. constexpr F32 LL_PING_BASED_TIMEOUT_DUMMY = 0.f;
  138. // *NOTE: Maybe these factors shouldn't include the msec to sec conversion
  139. // implicitly. However, all units should be MKS.
  140. // factor * averaged ping
  141. constexpr F32 LL_SEMIRELIABLE_TIMEOUT_FACTOR = 5.f / 1000.f;
  142. // factor * averaged ping
  143. constexpr F32 LL_RELIABLE_TIMEOUT_FACTOR = 5.f / 1000.f;
  144. // factor * averaged ping
  145. constexpr F32 LL_FILE_XFER_TIMEOUT_FACTOR = 5.f / 1000.f;
  146. // factor * averaged ping for marking packets "Lost"
  147. constexpr F32 LL_LOST_TIMEOUT_FACTOR = 16.f / 1000.f;
  148. // Maximum amount of time before considering something "lost"
  149. constexpr F32 LL_MAX_LOST_TIMEOUT = 5.f;
  150. constexpr S32 MAX_MESSAGE_COUNT_NUM = 1024;
  151. // Forward declarations
  152. class LLCircuit;
  153. class LLVector3;
  154. class LLVector4;
  155. class LLVector3d;
  156. class LLQuaternion;
  157. class LLUUID;
  158. class LLMessageSystem;
  159. class LLPumpIO;
  160. // Message system exceptional condition handlers.
  161. enum EMessageException
  162. {
  163. MX_UNREGISTERED_MESSAGE, // Message number not part of template
  164. MX_PACKET_TOO_SHORT, // Invalid, shorter than minimum packet size
  165. MX_RAN_OFF_END_OF_PACKET, // Ran off the end of the packet during decode
  166. MX_WROTE_PAST_BUFFER_SIZE // Wrote past buffer size in zero code expand
  167. };
  168. typedef void (*msg_exception_callback)(LLMessageSystem*, void*,
  169. EMessageException);
  170. // Message data pieces are used to collect the data called for by the message
  171. // template
  172. class LLMsgData;
  173. class LLMsgBlkData;
  174. class LLMessageTemplate;
  175. class LLMessagePollInfo;
  176. class LLMessageBuilder;
  177. class LLTemplateMessageBuilder;
  178. class LLSDMessageBuilder;
  179. class LLMessageReader;
  180. class LLTemplateMessageReader;
  181. class LLSDMessageReader;
  182. class LLUseCircuitCodeResponder
  183. {
  184. protected:
  185. LOG_CLASS(LLUseCircuitCodeResponder);
  186. public:
  187. virtual ~LLUseCircuitCodeResponder() = default;
  188. virtual void complete(const LLHost& host, const LLUUID& agent) const = 0;
  189. };
  190. #if LL_USE_FIBER_AWARE_MUTEX
  191. // SL-12204: We have observed crashes when consumer code sets
  192. // LLMessageSystem::mMessageReader, assuming that all subsequent processing of
  193. // the current message will use the same mMessageReader value, only to have a
  194. // different fiber sneak in and replace mMessageReader before completion. This
  195. // is a limitation of sharing a stateful global resource for message parsing;
  196. // instead code receiving a new message should instantiate a (trivially
  197. // constructed) local message parser and use that.
  198. //
  199. // Until then, when one fiber sets a particular LLMessageReader subclass as the
  200. // current message reader, ensure that no other fiber can replace it until the
  201. // first fiber has finished with its message.
  202. //
  203. // This is achieved with two helper classes. LLMessageSystem::mMessageReader is
  204. // now an LLMessageReaderPointer instance, which can efficiently compare or
  205. // dereference its contained LLMessageReader* but which cannot be directly
  206. // assigned. To change the value of LLMessageReaderPointer, you must
  207. // instantiate LockMessageReader with the LLMessageReader* you wish to make
  208. // current. mMessageReader will have that value for the lifetime of the
  209. // LockMessageReader instance, then revert to NULL. Moreover, as its name
  210. // implies, LockMessageReader locks the mutex in LLMessageReaderPointer so that
  211. // any other fiber instantiating LockMessageReader will block until the first
  212. // fiber has destroyed its instance.
  213. class LLMessageReaderPointer
  214. {
  215. // Only LockMessageReader can set mPtr.
  216. friend class LockMessageReader;
  217. public:
  218. LLMessageReaderPointer()
  219. : mPtr(NULL)
  220. {
  221. }
  222. // It is essential that comparison and dereferencing must be fast, which
  223. // is why we do not check for NULL when dereferencing.
  224. LL_INLINE LLMessageReader* operator->() const { return mPtr; }
  225. LL_INLINE bool operator==(const LLMessageReader* other) const
  226. {
  227. return mPtr == other;
  228. }
  229. LL_INLINE bool operator!=(const LLMessageReader* other) const
  230. {
  231. return mPtr != other;
  232. }
  233. private:
  234. LLMessageReader* mPtr;
  235. LL_MUTEX_TYPE mMutex;
  236. };
  237. // To set mMessageReader to NULL use an anonymous instance that is destroyed
  238. // immediately
  239. // LockMessageReader(gMessageSystem->mMessageReader, NULL);
  240. // Why do we still require going through LockMessageReader at all ? Because it
  241. // would be bad if any fiber set mMessageReader to NULL while another
  242. // fiber was still parsing a message.
  243. class LockMessageReader
  244. {
  245. public:
  246. LL_INLINE LockMessageReader(LLMessageReaderPointer& var,
  247. LLMessageReader* instance)
  248. : mVar(var.mPtr),
  249. mLock(var.mMutex)
  250. {
  251. mVar = instance;
  252. }
  253. LL_INLINE ~LockMessageReader()
  254. {
  255. mVar = NULL;
  256. }
  257. private:
  258. // Capture a reference to LLMessageReaderPointer::mPtr...
  259. decltype(LLMessageReaderPointer::mPtr)& mVar;
  260. // ...while holding a lock on LLMessageReaderPointer::mMutex
  261. LL_UNIQ_LOCK_TYPE mLock;
  262. };
  263. // LockMessageReader is great as long as you only need mMessageReader locked
  264. // during a single LLMessageSystem function call. However, empirically the
  265. // sequence from checkAllMessages() through processAcks() need mMessageReader
  266. // locked to LLTemplateMessageReader. Enforce that by making them require an
  267. // instance of LockMessageChecker.
  268. class LockMessageChecker;
  269. #endif // LL_USE_FIBER_AWARE_MUTEX
  270. class LLMessageSystem
  271. {
  272. friend class LLMessageHandlerBridge;
  273. friend class LockMessageChecker;
  274. protected:
  275. LOG_CLASS(LLMessageSystem);
  276. public:
  277. // Read file and build message templates
  278. LLMessageSystem(const std::string& filename, U32 port, S32 version_major,
  279. S32 version_minor, S32 version_patch,
  280. F32 heartbeat_interval, F32 circuit_timeout);
  281. ~LLMessageSystem();
  282. LL_INLINE bool isOK() const { return !mError; }
  283. LL_INLINE S32 getErrorCode() const { return mErrorCode; }
  284. // Read file and build message templates filename must point to a
  285. // valid string which specifies the path of a valid linden
  286. // template.
  287. void loadTemplateFile(const std::string& filename);
  288. // Lethods for building, sending, receiving, and handling messages
  289. void setHandlerFuncFast(const char* name,
  290. void (*handler_func)(LLMessageSystem*, void**),
  291. void** user_data = NULL);
  292. LL_INLINE void setHandlerFunc(const char* name,
  293. void (*handler_func)(LLMessageSystem*,
  294. void**),
  295. void** user_data = NULL)
  296. {
  297. setHandlerFuncFast(gMessageStringTable.getString(name),
  298. handler_func, user_data);
  299. }
  300. // Set a callback function for a message system exception.
  301. void setExceptionFunc(EMessageException exception,
  302. msg_exception_callback func, void* data = NULL);
  303. // Calls the specified exception func, and returns true if a function was
  304. // found and called. Otherwise returns false.
  305. bool callExceptionFunc(EMessageException exception);
  306. // Set a function that will be called once per packet processed with the
  307. // hashed message name and the time spent in the processing handler function
  308. // measured in seconds. JC
  309. typedef void (*msg_timing_callback)(const char* hashed_name, F32 time, void* data);
  310. void setTimingFunc(msg_timing_callback func, void* data = NULL);
  311. LL_INLINE msg_timing_callback getTimingCallback()
  312. {
  313. return mTimingCallback;
  314. }
  315. LL_INLINE void* getTimingCallbackData()
  316. {
  317. return mTimingCallbackData;
  318. }
  319. // This method returns true if the code is in the circuit codes map.
  320. LL_INLINE bool isCircuitCodeKnown(U32 code) const
  321. {
  322. return mCircuitCodes.count(code) != 0;
  323. }
  324. // Usually called in response to an AddCircuitCode message, but may also be
  325. // called by the login process.
  326. bool addCircuitCode(U32 code, const LLUUID& session_id);
  327. // Number of seconds that we want to block waiting for data, returns
  328. // true if data was received:
  329. bool poll(F32 seconds);
  330. #if LL_USE_FIBER_AWARE_MUTEX
  331. // Returns true if a valid, on-circuit message has been received.
  332. bool checkMessages(LockMessageChecker&, S64 frame_count = 0);
  333. void processAcks(LockMessageChecker&, F32 collect_time = 0.f);
  334. #else
  335. // Returns true if a valid, on-circuit message has been received.
  336. bool checkMessages(S64 frame_count = 0);
  337. void processAcks(F32 collect_time = 0.f);
  338. #endif
  339. bool isMessageFast(const char* msg);
  340. LL_INLINE bool isMessage(const char* msg)
  341. {
  342. return isMessageFast(gMessageStringTable.getString(msg));
  343. }
  344. void dumpPacketToLog();
  345. char* getMessageName();
  346. const LLHost& getSender() const;
  347. // getSender() is preferred
  348. LL_INLINE U32 getSenderIP() const { return mLastSender.getAddress(); }
  349. // getSender() is preferred
  350. LL_INLINE U32 getSenderPort() const { return mLastSender.getPort(); }
  351. LL_INLINE const LLHost& getReceivingInterface() const
  352. {
  353. return mLastReceivingIF;
  354. }
  355. // This method returns the uuid associated with the sender. The
  356. // UUID will be null if it is not yet known or is a server
  357. // circuit.
  358. const LLUUID& getSenderID() const;
  359. // This method returns the session id associated with the last
  360. // sender.
  361. const LLUUID& getSenderSessionID() const;
  362. #if 0 // Unused
  363. // Set & get the session id
  364. LL_INLINE void setMySessionID(const LLUUID& id) { mSessionID = id; }
  365. LL_INLINE const LLUUID& getMySessionID() { return mSessionID; }
  366. #endif
  367. void newMessageFast(const char* name);
  368. void newMessage(const char* name);
  369. void copyMessageReceivedToSend();
  370. void clearMessage();
  371. void nextBlockFast(const char* blockname);
  372. void nextBlock(const char* blockname);
  373. void addBinaryDataFast(const char* varname, const void* data, S32 size);
  374. void addBinaryData(const char* varname, const void* data, S32 size);
  375. // Typed, checks storage space:
  376. void addBoolFast(const char* varname, bool b);
  377. void addBool(const char* varname, bool b);
  378. void addS8Fast(const char* varname, S8 s);
  379. void addS8(const char* varname, S8 s);
  380. void addU8Fast(const char* varname, U8 u);
  381. void addU8(const char* varname, U8 u);
  382. void addS16Fast(const char* varname, S16 i);
  383. void addS16(const char* varname, S16 i);
  384. void addU16Fast(const char* varname, U16 i);
  385. void addU16(const char* varname, U16 i);
  386. void addF32Fast(const char* varname, F32 f);
  387. void addF32(const char* varname, F32 f);
  388. void addS32Fast(const char* varname, S32 s);
  389. void addS32(const char* varname, S32 s);
  390. void addU32Fast(const char* varname, U32 u);
  391. void addU32(const char* varname, U32 u);
  392. void addU64Fast(const char* varname, U64 lu);
  393. void addU64(const char* varname, U64 lu);
  394. void addF64Fast(const char* varname, F64 d);
  395. void addF64(const char* varname, F64 d);
  396. void addVector3Fast(const char* varname, const LLVector3& vec);
  397. void addVector3(const char* varname, const LLVector3& vec);
  398. void addVector4Fast(const char* varname, const LLVector4& vec);
  399. void addVector4(const char* varname, const LLVector4& vec);
  400. void addVector3dFast(const char* varname, const LLVector3d& vec);
  401. void addVector3d(const char* varname, const LLVector3d& vec);
  402. void addQuatFast(const char* varname, const LLQuaternion& quat);
  403. void addQuat(const char* varname, const LLQuaternion& quat);
  404. void addUUIDFast(const char* varname, const LLUUID& uuid);
  405. void addUUID(const char* varname, const LLUUID& uuid);
  406. void addIPAddrFast(const char* varname, U32 ip);
  407. void addIPAddr(const char* varname, U32 ip);
  408. void addIPPortFast(const char* varname, U16 port);
  409. void addIPPort(const char* varname, U16 port);
  410. void addStringFast(const char* varname, const char* s);
  411. void addString(const char* varname, const char* s);
  412. void addStringFast(const char* varname, const std::string& s);
  413. void addString(const char* varname, const std::string& s);
  414. S32 getCurrentSendTotal() const;
  415. LL_INLINE TPACKETID getCurrentRecvPacketID() { return mCurrentRecvPacketID; }
  416. // This method checks for current send total and returns true if
  417. // you need to go to the next block type or need to start a new
  418. // message. Specify the current blockname to check block counts,
  419. // otherwise the method only checks against MTU.
  420. bool isSendFull(const char* blockname = NULL);
  421. bool isSendFullFast(const char* blockname = NULL);
  422. // *TODO: Babbage: Remove this horror.
  423. bool removeLastBlock();
  424. S32 zeroCode(U8** data, S32* data_size);
  425. S32 zeroCodeExpand(U8** data, S32* data_size);
  426. // Uses ping-based retry.
  427. S32 sendReliable(const LLHost& host, U32 retries_factor = 1);
  428. // Uses ping-based retry
  429. LL_INLINE S32 sendReliable(U32 circuit)
  430. {
  431. return sendReliable(findHost(circuit));
  432. }
  433. // Use this one if you DON'T want automatic ping-based retry.
  434. S32 sendReliable(const LLHost& host, S32 retries,
  435. bool ping_based_retries, F32 timeout,
  436. void (*callback)(void**, S32), void** callback_data);
  437. S32 sendSemiReliable(const LLHost& host, void (*callback)(void**, S32),
  438. void** callback_data);
  439. S32 sendMessage(const LLHost& host);
  440. // Transmission alias
  441. LL_INLINE S32 sendMessage(U32 circuit)
  442. {
  443. return sendMessage(findHost(circuit));
  444. }
  445. /**
  446. gets binary data from the current message.
  447. @param blockname the name of the block in the message (from the message
  448. template)
  449. @param varname
  450. @param datap
  451. @param size expected size - set to zero to get any amount of data up to
  452. max_size. Make sure max_size is set in that case !
  453. @param blocknum
  454. @param max_size the max number of bytes to read
  455. */
  456. void getBinaryDataFast(const char* blockname, const char* varname,
  457. void* datap, S32 size, S32 blocknum = 0,
  458. S32 max_size = S32_MAX);
  459. void getBinaryData(const char* blockname, const char* varname, void* datap,
  460. S32 size, S32 blocknum = 0, S32 max_size = S32_MAX);
  461. void getBoolFast(const char* block, const char* var, bool& data, S32 blocknum = 0);
  462. void getBool(const char* block, const char* var, bool& data, S32 blocknum = 0);
  463. void getS8Fast(const char* block, const char* var, S8& data, S32 blocknum = 0);
  464. void getS8(const char* block, const char* var, S8& data, S32 blocknum = 0);
  465. void getU8Fast(const char* block, const char* var, U8& data, S32 blocknum = 0);
  466. void getU8(const char* block, const char* var, U8& data, S32 blocknum = 0);
  467. void getS16Fast(const char* block, const char* var, S16& data, S32 blocknum = 0);
  468. void getS16(const char* block, const char* var, S16& data, S32 blocknum = 0);
  469. void getU16Fast(const char* block, const char* var, U16& data, S32 blocknum = 0);
  470. void getU16(const char* block, const char* var, U16& data, S32 blocknum = 0);
  471. void getS32Fast(const char* block, const char* var, S32& data, S32 blocknum = 0);
  472. void getS32(const char* block, const char* var, S32& data, S32 blocknum = 0);
  473. void getF32Fast(const char* block, const char* var, F32& data, S32 blocknum = 0);
  474. void getF32(const char* block, const char* var, F32& data, S32 blocknum = 0);
  475. void getU32Fast(const char* block, const char* var, U32& data, S32 blocknum = 0);
  476. void getU32(const char* block, const char* var, U32& data, S32 blocknum = 0);
  477. void getU64Fast(const char* block, const char* var, U64& data, S32 blocknum = 0);
  478. void getU64(const char* block, const char* var, U64& data, S32 blocknum = 0);
  479. void getF64Fast(const char* block, const char* var, F64& data, S32 blocknum = 0);
  480. void getF64(const char* block, const char* var, F64& data, S32 blocknum = 0);
  481. void getVector3Fast(const char* block, const char* var, LLVector3& vec, S32 blocknum = 0);
  482. void getVector3(const char* block, const char* var, LLVector3& vec, S32 blocknum = 0);
  483. void getVector4Fast(const char* block, const char* var, LLVector4& vec, S32 blocknum = 0);
  484. void getVector4(const char* block, const char* var, LLVector4& vec, S32 blocknum = 0);
  485. void getVector3dFast(const char* block, const char* var, LLVector3d& vec, S32 blocknum = 0);
  486. void getVector3d(const char* block, const char* var, LLVector3d& vec, S32 blocknum = 0);
  487. void getQuatFast(const char* block, const char* var, LLQuaternion& q, S32 blocknum = 0);
  488. void getQuat(const char* block, const char* var, LLQuaternion& q, S32 blocknum = 0);
  489. void getUUIDFast(const char* block, const char* var, LLUUID& uuid, S32 blocknum = 0);
  490. void getUUID(const char* block, const char* var, LLUUID& uuid, S32 blocknum = 0);
  491. void getIPAddrFast(const char* block, const char* var, U32& ip, S32 blocknum = 0);
  492. void getIPAddr(const char* block, const char* var, U32& ip, S32 blocknum = 0);
  493. void getIPPortFast(const char* block, const char* var, U16& port, S32 blocknum = 0);
  494. void getIPPort(const char* block, const char* var, U16 &port, S32 blocknum = 0);
  495. void getStringFast(const char* block, const char* var, S32 buffer_size, char* buffer, S32 blocknum = 0);
  496. void getString(const char* block, const char* var, S32 buffer_size, char* buffer, S32 blocknum = 0);
  497. void getStringFast(const char* block, const char* var, std::string& outstr, S32 blocknum = 0);
  498. void getString(const char* block, const char* var, std::string& outstr, S32 blocknum = 0);
  499. void getCircuitInfo(LLSD& info) const;
  500. LL_INLINE U32 getOurCircuitCode() const { return mOurCircuitCode; }
  501. void enableCircuit(const LLHost& host, bool trusted);
  502. void disableCircuit(const LLHost& host);
  503. // Use this to inform a peer that they aren't currently trusted... This now
  504. // enqueues the request so that we can ensure that we only send one deny
  505. // per circuit per message loop so that this doesn't become a DoS. The
  506. // actual sending is done by reallySendDenyTrustedCircuit().
  507. void sendDenyTrustedCircuit(const LLHost& host);
  508. // Change this message to be UDP black listed.
  509. void banUdpMessage(const std::string& name);
  510. void setCircuitAllowTimeout(const LLHost& host, bool allow);
  511. void setCircuitTimeoutCallback(const LLHost& host,
  512. void (*callback_func)(const LLHost&, void*),
  513. void* user_data);
  514. bool checkCircuitBlocked(U32 circuit);
  515. bool checkCircuitAlive(U32 circuit);
  516. bool checkCircuitAlive(const LLHost& host);
  517. LL_INLINE void setCircuitProtection(bool b) { mProtected = b; }
  518. U32 findCircuitCode(const LLHost& host);
  519. LLHost findHost(U32 circuit_code);
  520. bool has(const char* blockname) const;
  521. S32 getNumberOfBlocksFast(const char* blockname) const;
  522. S32 getNumberOfBlocks(const char* blockname) const;
  523. S32 getSizeFast(const char* blockname, const char* varname) const;
  524. S32 getSize(const char* blockname, const char* varname) const;
  525. S32 getSizeFast(const char* blockname, S32 blocknum,
  526. const char* varname) const; // size in bytes of data
  527. S32 getSize(const char* blockname, S32 blocknum,
  528. const char* varname) const;
  529. // Resets receive counts for all message types to 0
  530. void resetReceiveCounts();
  531. // Dumps receive count for each message type to llinfos
  532. void dumpReceiveCounts();
  533. LL_INLINE bool isClear() const { return mMessageBuilder->isClear(); }
  534. S32 flush(const LLHost& host);
  535. LL_INLINE U32 getListenPort() const { return mPort; }
  536. void startLogging(); // starts verbose logging
  537. void stopLogging(); // flushes and closes file
  538. void summarizeLogs(std::ostream& str); // logs statistics
  539. S32 getReceiveSize() const;
  540. LL_INLINE S32 getReceiveCompressedSize() const { return mIncomingCompressedSize; }
  541. LL_INLINE S32 getReceiveBytes() const;
  542. LL_INLINE S32 getUnackedListSize() const { return mUnackedListSize; }
  543. #if 0
  544. const char* getCurrentSMessageName() const { return mCurrentSMessageName; }
  545. const char* getCurrentSBlockName() const { return mCurrentSBlockName; }
  546. #endif
  547. // Friends
  548. friend std::ostream& operator<<(std::ostream& s, LLMessageSystem &msg);
  549. // Max time to process messages before warning and dumping (neg to disable)
  550. LL_INLINE void setMaxMessageTime(F32 secs) { mMaxMessageTime = secs; }
  551. // Max number of messages before dumping (neg to disable)
  552. LL_INLINE void setMaxMessageCounts(S32 num) { mMaxMessageCounts = num; }
  553. // Get the current message system time in microseconds
  554. static U64 getMessageTimeUsecs(bool update = false);
  555. // Get the current message system time in seconds
  556. static F64 getMessageTimeSeconds(bool update = false);
  557. static void setTimeDecodes(bool b);
  558. static void setTimeDecodesSpamThreshold(F32 seconds);
  559. // Message handlers internal to the message systesm
  560. static void processAddCircuitCode(LLMessageSystem* msg, void**);
  561. static void processUseCircuitCode(LLMessageSystem* msg, void**);
  562. static void processError(LLMessageSystem* msg, void**);
  563. // Dispatch llsd message to http node tree
  564. static void dispatch(const std::string& msg_name, const LLSD& message);
  565. static void dispatch(const std::string& msg_name, const LLSD& message,
  566. LLHTTPNode::ResponsePtr responsep);
  567. void setMessageBans(const LLSD& trusted, const LLSD& untrusted);
  568. /**
  569. * @brief send an error message to the host. This is a helper method.
  570. *
  571. * @param host Destination host.
  572. * @param agent_id Destination agent id (may be null)
  573. * @param code An HTTP status compatible error code.
  574. * @param token A specific short string based message
  575. * @param id The transactionid/uniqueid/sessionid whatever.
  576. * @param system The hierarchical path to the system (255 bytes)
  577. * @param message Human readable message (1200 bytes)
  578. * @param data Extra info.
  579. * @return Returns value returned from sendReliable().
  580. */
  581. S32 sendError(const LLHost& host, const LLUUID& agent_id, S32 code,
  582. const std::string& token, const LLUUID& id,
  583. const std::string& system, const std::string& message,
  584. const LLSD& data);
  585. // Check UDP messages and pump http_pump to receive HTTP messages.
  586. #if LL_USE_FIBER_AWARE_MUTEX
  587. bool checkAllMessages(LockMessageChecker&, S64 frame_count,
  588. LLPumpIO* pumpp);
  589. #else
  590. bool checkAllMessages(S64 frame_count, LLPumpIO* pumpp);
  591. #endif
  592. void setHttpOptionsWithTimeout(U32 timeout);
  593. private:
  594. LLSD getReceivedMessageLLSD() const;
  595. LLSD getBuiltMessageLLSD() const;
  596. // NOTE: Babbage: only use to support legacy misuse of the LLMessageSystem
  597. // API where values are dangerously written as one type and read as
  598. // another. LLSD does not support dangerous conversions and so converting
  599. // the message to an LLSD would result in the reads failing. All code which
  600. // misuses the message system in this way should be made safe but while the
  601. // unsafe code is run in old processes, this method should be used to
  602. // forward unsafe messages.
  603. LLSD wrapReceivedTemplateData() const;
  604. LLSD wrapBuiltTemplateData() const;
  605. void clearReceiveState();
  606. S32 sendMessage(const LLHost& host, const char* name, const LLSD& message);
  607. // Really sends the DenyTrustedCircuit message to a given host
  608. // related to sendDenyTrustedCircuit()
  609. void reallySendDenyTrustedCircuit(const LLHost& host);
  610. typedef boost::function<void(S32)> UntrustedCallback_t;
  611. void sendUntrustedSimulatorMessageCoro(const LLHost& dest_host,
  612. const char* msg_name,
  613. const LLSD& body,
  614. UntrustedCallback_t callback);
  615. void addTemplate(LLMessageTemplate* templatep);
  616. void logMsgFromInvalidCircuit(const LLHost& sender, bool recv_reliable);
  617. void logTrustedMsgFromUntrustedCircuit(const LLHost& sender);
  618. void logValidMsg(LLCircuitData* cdp, const LLHost& sender,
  619. bool recv_reliable, bool recv_resent, bool recv_acks);
  620. void logRanOffEndOfPacket(const LLHost& sender);
  621. bool callHandler(const char* name, bool trusted_source = false);
  622. void init(); // Constuctor shared initialisation.
  623. // Finds, creates or revives circuit for host as needed
  624. LLCircuitData* findCircuit(const LLHost& host, bool reset_packet_id);
  625. private:
  626. U8 mSendBuffer[MAX_BUFFER_SIZE];
  627. S32 mSendSize;
  628. public:
  629. // Set this flag to true when you want *very* verbose logs.
  630. bool mVerboseLog;
  631. bool mProtected;
  632. // Does the outgoing message require a pos ack ?
  633. bool mSendReliable;
  634. LLPacketRing mPacketRing;
  635. LLReliablePacketParams mReliablePacketParams;
  636. F32 mMessageFileVersionNumber;
  637. S32 mSystemVersionMajor;
  638. S32 mSystemVersionMinor;
  639. S32 mSystemVersionPatch;
  640. S32 mSystemVersionServer;
  641. U32 mVersionFlags;
  642. U32 mNumberHighFreqMessages;
  643. U32 mNumberMediumFreqMessages;
  644. U32 mNumberLowFreqMessages;
  645. S32 mPort;
  646. S32 mSocket;
  647. // Total packets in, including compressed and uncompressed
  648. U32 mPacketsIn;
  649. // Total packets out, including compressed and uncompressed
  650. U32 mPacketsOut;
  651. // Total bytes in, including compressed and uncompressed
  652. U64 mBytesIn;
  653. // Total bytes out, including compressed and uncompressed
  654. U64 mBytesOut;
  655. // Total compressed packets in
  656. U32 mCompressedPacketsIn;
  657. // Total compressed packets out
  658. U32 mCompressedPacketsOut;
  659. // Total reliable packets in
  660. U32 mReliablePacketsIn;
  661. // Total reliable packets out
  662. U32 mReliablePacketsOut;
  663. // Total dropped packets in
  664. U32 mDroppedPackets;
  665. // Total resent packets out
  666. U32 mResentPackets;
  667. // Total resend failure packets out
  668. U32 mFailedResendPackets;
  669. // Total # of off-circuit packets rejected
  670. U32 mOffCircuitPackets;
  671. // Total # of on-circuit but invalid packets rejected
  672. U32 mInvalidOnCircuitPackets;
  673. // Total uncompressed size of compressed packets in
  674. S64 mUncompressedBytesIn;
  675. // Total uncompressed size of compressed packets out
  676. S64 mUncompressedBytesOut;
  677. // Total compressed size of compressed packets in
  678. S64 mCompressedBytesIn;
  679. // Total compressed size of compressed packets out
  680. S64 mCompressedBytesOut;
  681. // Total size of all uncompressed packets in
  682. S64 mTotalBytesIn;
  683. // Total size of all uncompressed packets out
  684. S64 mTotalBytesOut;
  685. LLCircuit mCircuitInfo;
  686. // Used to print circuit debug info every couple minutes
  687. F64 mCircuitPrintTime;
  688. F32 mCircuitPrintFreq; // In seconds
  689. U32 mOurCircuitCode;
  690. S32 mSendPacketFailureCount;
  691. S32 mUnackedListDepth;
  692. S32 mUnackedListSize;
  693. S32 mDSMaxListDepth;
  694. fast_hmap<U64, U32> mIPPortToCircuitCode;
  695. fast_hmap<U32, U64> mCircuitCodeToIPPort;
  696. typedef std::map<const char*, LLMessageTemplate*> template_name_map_t;
  697. typedef fast_hmap<U32, LLMessageTemplate*> template_number_map_t;
  698. private:
  699. template_name_map_t mMessageTemplates;
  700. template_number_map_t mMessageNumbers;
  701. LLCore::HttpOptions::ptr_t mHttpOptions;
  702. // The mCircuitCodes is a map from circuit codes to session Ids. This
  703. // allows us to verify sessions on connect.
  704. typedef fast_hmap<U32, LLUUID> code_session_map_t;
  705. code_session_map_t mCircuitCodes;
  706. // Viewers need to track a process session in order to make sure that no
  707. // one gives them a bad circuit code.
  708. LLUUID mSessionID;
  709. class LLMessageCountInfo
  710. {
  711. public:
  712. U32 mMessageNum;
  713. U32 mMessageBytes;
  714. bool mInvalid;
  715. };
  716. LLMessagePollInfo* mPollInfop;
  717. U8 mEncodedRecvBuffer[MAX_BUFFER_SIZE];
  718. U8 mTrueReceiveBuffer[MAX_BUFFER_SIZE];
  719. S32 mTrueReceiveSize;
  720. // Must be valid during decode
  721. bool mError;
  722. S32 mErrorCode;
  723. // The last time we dumped resends
  724. F64 mResendDumpTime;
  725. LLMessageCountInfo mMessageCountList[MAX_MESSAGE_COUNT_NUM];
  726. S32 mNumMessageCounts;
  727. F32 mReceiveTime;
  728. // Max number of seconds for processing messages
  729. F32 mMaxMessageTime;
  730. // Max number of messages to process before dumping
  731. S32 mMaxMessageCounts;
  732. F64 mMessageCountTime;
  733. // The current "message system time" (updated the first call to
  734. // checkMessages after a resetReceiveCount
  735. F64 mCurrentMessageTimeSeconds;
  736. // Message system exceptions
  737. typedef std::pair<msg_exception_callback, void*> exception_t;
  738. typedef std::map<EMessageException, exception_t> callbacks_t;
  739. callbacks_t mExceptionCallbacks;
  740. // Stuff for logging
  741. LLTimer mMessageSystemTimer;
  742. msg_timing_callback mTimingCallback;
  743. void* mTimingCallbackData;
  744. LLHost mLastSender;
  745. LLHost mLastReceivingIF;
  746. // Original size of compressed msg (0 if uncomp)
  747. S32 mIncomingCompressedSize;
  748. // Packet ID of current receive packet (for reporting)
  749. TPACKETID mCurrentRecvPacketID;
  750. LLMessageBuilder* mMessageBuilder;
  751. LLTemplateMessageBuilder* mTemplateMessageBuilder;
  752. LLSDMessageBuilder* mLLSDMessageBuilder;
  753. #if LL_USE_FIBER_AWARE_MUTEX
  754. LLMessageReaderPointer mMessageReader;
  755. #else
  756. LLMessageReader* mMessageReader;
  757. #endif
  758. LLTemplateMessageReader* mTemplateMessageReader;
  759. LLSDMessageReader* mLLSDMessageReader;
  760. // A list of the circuits that need to be sent DenyTrustedCircuit messages.
  761. typedef std::set<LLHost> host_set_t;
  762. host_set_t mDenyTrustedCircuitSet;
  763. };
  764. #if LL_USE_FIBER_AWARE_MUTEX
  765. // Implementation of LockMessageChecker depends on definition of
  766. // LLMessageSystem, hence must follow it.
  767. class LockMessageChecker: public LockMessageReader
  768. {
  769. public:
  770. LockMessageChecker(LLMessageSystem* msgsystem);
  771. // For convenience, provide forwarding wrappers so you can call, e.g.,
  772. // checkAllMessages() on your LockMessageChecker instance instead of
  773. // perfect forwarding to avoid having to maintain these wrappers in sync
  774. // with the target methods.
  775. template <typename... ARGS>
  776. LL_INLINE bool checkAllMessages(ARGS&&... args)
  777. {
  778. return mMessageSystem->checkAllMessages(*this,
  779. std::forward<ARGS>(args)...);
  780. }
  781. template <typename... ARGS>
  782. LL_INLINE bool checkMessages(ARGS&&... args)
  783. {
  784. return mMessageSystem->checkMessages(*this,
  785. std::forward<ARGS>(args)...);
  786. }
  787. template <typename... ARGS>
  788. LL_INLINE void processAcks(ARGS&&... args)
  789. {
  790. return mMessageSystem->processAcks(*this, std::forward<ARGS>(args)...);
  791. }
  792. private:
  793. LLMessageSystem* mMessageSystem;
  794. };
  795. #endif // LL_USE_FIBER_AWARE_MUTEX
  796. // External hook into messaging system
  797. extern LLMessageSystem* gMessageSystemp;
  798. // Must specific overall system version, which is used to determine
  799. // if a patch is available in the message template checksum verification.
  800. // Returns true if able to initialize system.
  801. bool start_messaging_system(const std::string& template_name, U32 port,
  802. S32 ver_major, S32 ver_minor, S32 ver_patch,
  803. const LLUseCircuitCodeResponder* responder,
  804. F32 heartbeat_interval, F32 circuit_timeout);
  805. void end_messaging_system(bool print_summary = true);
  806. void null_message_callback(LLMessageSystem* msg, void**data);
  807. ///////////////////////////////////////////////////////////////////////////////
  808. // LLGenericStreamingMessage helper class for Generic Streaming messages
  809. ///////////////////////////////////////////////////////////////////////////////
  810. class LLGenericStreamingMessage
  811. {
  812. public:
  813. enum Method : U16
  814. {
  815. METHOD_GLTF_MATERIAL_OVERRIDE = 0x4175,
  816. METHOD_UNKNOWN = 0xFFFF,
  817. };
  818. LL_INLINE LLGenericStreamingMessage()
  819. : mMethod(METHOD_UNKNOWN)
  820. {
  821. }
  822. void unpack(LLMessageSystem* msg);
  823. public:
  824. std::string mData;
  825. Method mMethod;
  826. };
  827. //
  828. // Inlines
  829. //
  830. #ifndef LL_BIG_ENDIAN
  831. # error Unknown endianness. Did you omit to include llpreprocessor.h ?
  832. #endif
  833. // Saves from inlining llerrs messages... HB
  834. LL_NO_INLINE void swizzle_size_error(size_t n, size_t s);
  835. static LL_INLINE void* htonmemcpy(void* vs, const void* vct,
  836. EMsgVariableType type, size_t n)
  837. {
  838. char* s = (char*)vs;
  839. const char* ct = (const char*)vct;
  840. #if LL_BIG_ENDIAN
  841. S32 i, length;
  842. #endif
  843. switch (type)
  844. {
  845. case MVT_FIXED:
  846. case MVT_VARIABLE:
  847. case MVT_U8:
  848. case MVT_S8:
  849. case MVT_BOOL:
  850. case MVT_LLUUID:
  851. case MVT_IP_ADDR: // these two are swizzled in the getters and setters
  852. case MVT_IP_PORT: // these two are swizzled in the getters and setters
  853. return(memcpy(s, ct, n));
  854. case MVT_U16:
  855. case MVT_S16:
  856. if (n != 2)
  857. {
  858. swizzle_size_error(n, 2);
  859. }
  860. #if LL_BIG_ENDIAN
  861. *(s + 1) = *(ct);
  862. *(s) = *(ct + 1);
  863. return vs;
  864. #else
  865. return memcpy(s, ct, n);
  866. #endif
  867. case MVT_U32:
  868. case MVT_S32:
  869. case MVT_F32:
  870. if (n != 4)
  871. {
  872. swizzle_size_error(n, 4);
  873. }
  874. #if LL_BIG_ENDIAN
  875. *(s + 3) = *(ct);
  876. *(s + 2) = *(ct + 1);
  877. *(s + 1) = *(ct + 2);
  878. *(s) = *(ct + 3);
  879. return vs;
  880. #else
  881. return memcpy(s, ct, n);
  882. #endif
  883. case MVT_U64:
  884. case MVT_S64:
  885. case MVT_F64:
  886. if (n != 8)
  887. {
  888. swizzle_size_error(n, 8);
  889. }
  890. #if LL_BIG_ENDIAN
  891. *(s + 7) = *(ct);
  892. *(s + 6) = *(ct + 1);
  893. *(s + 5) = *(ct + 2);
  894. *(s + 4) = *(ct + 3);
  895. *(s + 3) = *(ct + 4);
  896. *(s + 2) = *(ct + 5);
  897. *(s + 1) = *(ct + 6);
  898. *s = *(ct + 7);
  899. return vs;
  900. #else
  901. return memcpy(s, ct, n);
  902. #endif
  903. case MVT_LLVector3:
  904. case MVT_LLQuaternion: // We only send x, y, z and infer w (we set x, y, z to ensure that w >= 0)
  905. if (n != 12)
  906. {
  907. swizzle_size_error(n, 12);
  908. }
  909. #if LL_BIG_ENDIAN
  910. htonmemcpy(s + 8, ct + 8, MVT_F32, 4);
  911. htonmemcpy(s + 4, ct + 4, MVT_F32, 4);
  912. return htonmemcpy(s, ct, MVT_F32, 4);
  913. #else
  914. return memcpy(s, ct, n);
  915. #endif
  916. case MVT_LLVector3d:
  917. if (n != 24)
  918. {
  919. swizzle_size_error(n, 24);
  920. }
  921. #if LL_BIG_ENDIAN
  922. htonmemcpy(s + 16, ct + 16, MVT_F64, 8);
  923. htonmemcpy(s + 8, ct + 8, MVT_F64, 8);
  924. return htonmemcpy(s, ct, MVT_F64, 8);
  925. #else
  926. return memcpy(s, ct, n);
  927. #endif
  928. case MVT_LLVector4:
  929. if (n != 16)
  930. {
  931. swizzle_size_error(n, 16);
  932. }
  933. #if LL_BIG_ENDIAN
  934. htonmemcpy(s + 12, ct + 12, MVT_F32, 4);
  935. htonmemcpy(s + 8, ct + 8, MVT_F32, 4);
  936. htonmemcpy(s + 4, ct + 4, MVT_F32, 4);
  937. return htonmemcpy(s, ct, MVT_F32, 4);
  938. #else
  939. return memcpy(s, ct, n);
  940. #endif
  941. case MVT_U16Vec3:
  942. if (n != 6)
  943. {
  944. swizzle_size_error(n, 6);
  945. }
  946. #if LL_BIG_ENDIAN
  947. htonmemcpy(s + 4, ct + 4, MVT_U16, 2);
  948. htonmemcpy(s + 2, ct + 2, MVT_U16, 2);
  949. return htonmemcpy(s, ct, MVT_U16, 2);
  950. #else
  951. return memcpy(s, ct, n);
  952. #endif
  953. case MVT_U16Quat:
  954. if (n != 8)
  955. {
  956. swizzle_size_error(n, 8);
  957. }
  958. #if LL_BIG_ENDIAN
  959. htonmemcpy(s + 6, ct + 6, MVT_U16, 2);
  960. htonmemcpy(s + 4, ct + 4, MVT_U16, 2);
  961. htonmemcpy(s + 2, ct + 2, MVT_U16, 2);
  962. return htonmemcpy(s, ct, MVT_U16, 2);
  963. #else
  964. return memcpy(s, ct, n);
  965. #endif
  966. case MVT_S16Array:
  967. if (n % 2)
  968. {
  969. swizzle_size_error(n, n + 1);
  970. }
  971. #if LL_BIG_ENDIAN
  972. length = n % 2;
  973. for (i = 1; i < length; ++i)
  974. {
  975. htonmemcpy(s + i * 2, ct + i * 2, MVT_S16, 2);
  976. }
  977. return htonmemcpy(s, ct, MVT_S16, 2);
  978. #else
  979. return memcpy(s, ct, n);
  980. #endif
  981. default:
  982. return memcpy(s, ct, n);
  983. }
  984. }
  985. LL_INLINE void* ntohmemcpy(void* s, const void* ct, EMsgVariableType type,
  986. size_t n)
  987. {
  988. return htonmemcpy(s, ct, type, n);
  989. }
  990. #endif