llpacketring.cpp 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. /**
  2. * @file llpacketring.cpp
  3. * @brief implementation of LLPacketRing class for a packet.
  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. #include "linden_common.h"
  33. #include "llpacketring.h"
  34. #if LL_WINDOWS
  35. # include <winsock2.h>
  36. #else
  37. # include <sys/socket.h>
  38. # include <netinet/in.h>
  39. #endif
  40. #include "llmessage.h"
  41. #include "llnet.h"
  42. #include "llproxy.h"
  43. #include "llrand.h"
  44. #include "lltimer.h"
  45. ///////////////////////////////////////////////////////////////////////////////
  46. // LLPacketBuffer class. Used to be in its own llpacketbuffer.h/cpp module, but
  47. // is only used by LLPacketRing, so I moved it here. HB
  48. ///////////////////////////////////////////////////////////////////////////////
  49. class LLPacketBuffer
  50. {
  51. public:
  52. LLPacketBuffer(const LLHost& host, const char* datap, S32 size);
  53. LL_INLINE LLPacketBuffer(S32 socket) { init(socket); }
  54. void init(S32 socket);
  55. LL_INLINE S32 getSize() const { return mSize; }
  56. LL_INLINE const char* getData() const { return mData; }
  57. LL_INLINE LLHost getHost() const { return mHost; }
  58. LL_INLINE LLHost getReceivingInterface() const { return mReceivingIF; }
  59. protected:
  60. LLHost mHost; // Source/dest IP and port
  61. LLHost mReceivingIF; // Source/dest IP and port
  62. char mData[NET_BUFFER_SIZE]; // Packet data
  63. S32 mSize; // Size of buffer in bytes
  64. };
  65. LLPacketBuffer::LLPacketBuffer(const LLHost& host, const char* datap, S32 size)
  66. : mHost(host)
  67. {
  68. mSize = 0;
  69. mData[0] = '!';
  70. if (size > NET_BUFFER_SIZE)
  71. {
  72. llerrs << "Sending packet > " << NET_BUFFER_SIZE << " of size " << size
  73. << llendl;
  74. }
  75. if (datap)
  76. {
  77. memcpy(mData, datap, size);
  78. mSize = size;
  79. }
  80. }
  81. void LLPacketBuffer::init(S32 socket)
  82. {
  83. mSize = receive_packet(socket, mData);
  84. mHost = get_sender();
  85. mReceivingIF = get_receiving_interface();
  86. }
  87. ///////////////////////////////////////////////////////////////////////////////
  88. // LLPacketRing class
  89. ///////////////////////////////////////////////////////////////////////////////
  90. LLPacketRing::LLPacketRing()
  91. : mUseInThrottle(false),
  92. mUseOutThrottle(false),
  93. mInThrottle(256000.f),
  94. mOutThrottle(64000.f),
  95. mActualBitsIn(0),
  96. mActualBitsOut(0),
  97. mMaxBufferLength(64000),
  98. mInBufferLength(0),
  99. mOutBufferLength(0)
  100. {
  101. }
  102. LLPacketRing::~LLPacketRing()
  103. {
  104. cleanup();
  105. }
  106. void LLPacketRing::cleanup()
  107. {
  108. while (!mReceiveQueue.empty())
  109. {
  110. LLPacketBuffer* packetp = mReceiveQueue.front();
  111. delete packetp;
  112. mReceiveQueue.pop();
  113. }
  114. while (!mSendQueue.empty())
  115. {
  116. LLPacketBuffer* packetp = mSendQueue.front();
  117. delete packetp;
  118. mSendQueue.pop();
  119. }
  120. }
  121. S32 LLPacketRing::receiveFromRing(S32 socket, char* datap)
  122. {
  123. if (mInThrottle.checkOverflow(0))
  124. {
  125. // We do not have enough bandwidth, do not give them a packet.
  126. return 0;
  127. }
  128. LLPacketBuffer* packetp = NULL;
  129. if (mReceiveQueue.empty())
  130. {
  131. // No packets on the queue, do not give them any.
  132. return 0;
  133. }
  134. S32 packet_size = 0;
  135. packetp = mReceiveQueue.front();
  136. mReceiveQueue.pop();
  137. packet_size = packetp->getSize();
  138. if (packetp->getData() != NULL)
  139. {
  140. memcpy(datap, packetp->getData(), packet_size);
  141. }
  142. // need to set sender IP/port!!
  143. mLastSender = packetp->getHost();
  144. mLastReceivingIF = packetp->getReceivingInterface();
  145. delete packetp;
  146. this->mInBufferLength -= packet_size;
  147. // Adjust the throttle
  148. mInThrottle.throttleOverflow(packet_size * 8.f);
  149. return packet_size;
  150. }
  151. S32 LLPacketRing::receivePacket(S32 socket, char* datap)
  152. {
  153. S32 packet_size = 0;
  154. // If using the throttle, simulate a limited size input buffer.
  155. if (mUseInThrottle)
  156. {
  157. bool done = false;
  158. // Push any current net packet (if any) onto delay ring
  159. while (!done)
  160. {
  161. LLPacketBuffer* packetp = new LLPacketBuffer(socket);
  162. if (packetp && packetp->getSize())
  163. {
  164. mActualBitsIn += packetp->getSize() * 8;
  165. }
  166. // If we faked packet loss, then we do not have a packet to use for
  167. // buffer overflow testing (no packetp == faked packet loss).
  168. if (packetp)
  169. {
  170. if (mInBufferLength + packetp->getSize() > mMaxBufferLength)
  171. {
  172. // Toss it.
  173. llwarns << "Throwing away packet, overflowing buffer"
  174. << llendl;
  175. delete packetp;
  176. packetp = NULL;
  177. }
  178. else if (packetp->getSize())
  179. {
  180. mReceiveQueue.push(packetp);
  181. mInBufferLength += packetp->getSize();
  182. }
  183. else
  184. {
  185. delete packetp;
  186. packetp = NULL;
  187. done = true;
  188. }
  189. }
  190. }
  191. // Now, grab data off of the receive queue according to our throttled
  192. // bandwidth settings.
  193. packet_size = receiveFromRing(socket, datap);
  194. }
  195. else
  196. {
  197. // No delay, pull straight from net
  198. if (LLProxy::isSOCKSProxyEnabled())
  199. {
  200. U8 buffer[NET_BUFFER_SIZE + SOCKS_HEADER_SIZE];
  201. packet_size = receive_packet(socket, (char*)((void*)buffer));
  202. if (packet_size > SOCKS_HEADER_SIZE)
  203. {
  204. // *FIX: we are assuming ATYP is 0x01 (IPv4), not 0x03
  205. // (hostname) or 0x04 (IPv6)
  206. memcpy(datap, buffer + SOCKS_HEADER_SIZE,
  207. packet_size - SOCKS_HEADER_SIZE);
  208. proxywrap_t* header = (proxywrap_t*)((void*)buffer);
  209. mLastSender.setAddress(header->addr);
  210. mLastSender.setPort(ntohs(header->port));
  211. packet_size -= SOCKS_HEADER_SIZE; // The unwrapped packet size
  212. }
  213. else
  214. {
  215. packet_size = 0;
  216. }
  217. }
  218. else
  219. {
  220. packet_size = receive_packet(socket, datap);
  221. mLastSender = get_sender();
  222. }
  223. mLastReceivingIF = get_receiving_interface();
  224. }
  225. return packet_size;
  226. }
  227. bool LLPacketRing::sendPacket(int h_socket, char* send_buffer, S32 buf_size,
  228. LLHost host)
  229. {
  230. bool status = true;
  231. if (!mUseOutThrottle)
  232. {
  233. return sendPacketImpl(h_socket, send_buffer, buf_size, host);
  234. }
  235. else
  236. {
  237. mActualBitsOut += buf_size * 8;
  238. LLPacketBuffer* packetp = NULL;
  239. // See if we have got enough throttle to send a packet.
  240. while (!mOutThrottle.checkOverflow(0.f))
  241. {
  242. // While we have enough bandwidth, send a packet from the queue or
  243. // the current packet
  244. S32 packet_size = 0;
  245. if (!mSendQueue.empty())
  246. {
  247. // Send a packet off of the queue
  248. LLPacketBuffer* packetp = mSendQueue.front();
  249. mSendQueue.pop();
  250. mOutBufferLength -= packetp->getSize();
  251. packet_size = packetp->getSize();
  252. status = sendPacketImpl(h_socket, packetp->getData(),
  253. packet_size, packetp->getHost());
  254. delete packetp;
  255. // Update the throttle
  256. mOutThrottle.throttleOverflow(packet_size * 8.f);
  257. }
  258. else
  259. {
  260. // If the queue is empty, we can just send this packet right
  261. // away.
  262. status = sendPacketImpl(h_socket, send_buffer, buf_size, host);
  263. packet_size = buf_size;
  264. // Update the throttle
  265. mOutThrottle.throttleOverflow(packet_size * 8.f);
  266. // This was the packet we are sending now, there are no other
  267. // packets that we need to send
  268. return status;
  269. }
  270. }
  271. // We have not sent the incoming packet, add it to the queue
  272. if (mOutBufferLength + buf_size > mMaxBufferLength)
  273. {
  274. // Nuke this packet, we overflowed the buffer. Toss it.
  275. llwarns << "Throwing away outbound packet, overflowing buffer"
  276. << llendl;
  277. }
  278. else
  279. {
  280. static LLTimer queue_timer;
  281. if (mOutBufferLength > 4192 &&
  282. queue_timer.getElapsedTimeF32() > 1.f)
  283. {
  284. // Add it to the queue
  285. llinfos << "Outbound packet queue " << mOutBufferLength
  286. << " bytes" << llendl;
  287. queue_timer.reset();
  288. }
  289. packetp = new LLPacketBuffer(host, send_buffer, buf_size);
  290. mOutBufferLength += packetp->getSize();
  291. mSendQueue.push(packetp);
  292. }
  293. }
  294. return status;
  295. }
  296. bool LLPacketRing::sendPacketImpl(int h_socket, const char* send_buffer,
  297. S32 buf_size, LLHost host)
  298. {
  299. if (!LLProxy::isSOCKSProxyEnabled())
  300. {
  301. return send_packet(h_socket, send_buffer, buf_size, host.getAddress(),
  302. host.getPort());
  303. }
  304. char headered_send_buffer[NET_BUFFER_SIZE + SOCKS_HEADER_SIZE];
  305. proxywrap_t* socks_header = (proxywrap_t*)((void*)&headered_send_buffer);
  306. socks_header->rsv = 0;
  307. socks_header->addr = host.getAddress();
  308. socks_header->port = htons(host.getPort());
  309. socks_header->atype = ADDRESS_IPV4;
  310. socks_header->frag = 0;
  311. memcpy(headered_send_buffer + SOCKS_HEADER_SIZE, send_buffer, buf_size);
  312. LLHost proxyhost = LLProxy::getInstance()->getUDPProxy();
  313. return send_packet(h_socket, headered_send_buffer,
  314. buf_size + SOCKS_HEADER_SIZE,
  315. proxyhost.getAddress(), proxyhost.getPort());
  316. }