diff options
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs')
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index 545a0bc..8bfab6a 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs | |||
@@ -89,6 +89,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
89 | /// </summary> | 89 | /// </summary> |
90 | public class LLUDPServer : OpenSimUDPBase | 90 | public class LLUDPServer : OpenSimUDPBase |
91 | { | 91 | { |
92 | /// <summary>Maximum transmission unit, or UDP packet size, for the LLUDP protocol</summary> | ||
93 | public const int MTU = 1400; | ||
94 | |||
92 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 95 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
93 | 96 | ||
94 | /// <summary>Handlers for incoming packets</summary> | 97 | /// <summary>Handlers for incoming packets</summary> |
@@ -267,38 +270,54 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
267 | { | 270 | { |
268 | int dataLength = data.Length; | 271 | int dataLength = data.Length; |
269 | bool doZerocode = (data[0] & Helpers.MSG_ZEROCODED) != 0; | 272 | bool doZerocode = (data[0] & Helpers.MSG_ZEROCODED) != 0; |
273 | bool doCopy = true; | ||
270 | 274 | ||
271 | // Frequency analysis of outgoing packet sizes shows a large clump of packets at each end of the spectrum. | 275 | // Frequency analysis of outgoing packet sizes shows a large clump of packets at each end of the spectrum. |
272 | // The vast majority of packets are less than 200 bytes, although due to asset transfers and packet splitting | 276 | // The vast majority of packets are less than 200 bytes, although due to asset transfers and packet splitting |
273 | // there are a decent number of packets in the 1000-1140 byte range. We allocate one of two sizes of data here | 277 | // there are a decent number of packets in the 1000-1140 byte range. We allocate one of two sizes of data here |
274 | // to accomodate for both common scenarios and provide ample room for ACK appending in both | 278 | // to accomodate for both common scenarios and provide ample room for ACK appending in both |
275 | int bufferSize = (dataLength > 180) ? Packet.MTU : 200; | 279 | int bufferSize = (dataLength > 180) ? LLUDPServer.MTU : 200; |
276 | 280 | ||
277 | UDPPacketBuffer buffer = new UDPPacketBuffer(udpClient.RemoteEndPoint, bufferSize); | 281 | UDPPacketBuffer buffer = new UDPPacketBuffer(udpClient.RemoteEndPoint, bufferSize); |
278 | 282 | ||
279 | // Zerocode if needed | 283 | // Zerocode if needed |
280 | if (doZerocode) | 284 | if (doZerocode) |
281 | { | 285 | { |
282 | try { dataLength = Helpers.ZeroEncode(data, dataLength, buffer.Data); } | 286 | try |
287 | { | ||
288 | dataLength = Helpers.ZeroEncode(data, dataLength, buffer.Data); | ||
289 | doCopy = false; | ||
290 | } | ||
283 | catch (IndexOutOfRangeException) | 291 | catch (IndexOutOfRangeException) |
284 | { | 292 | { |
285 | // The packet grew larger than the bufferSize while zerocoding. | 293 | // The packet grew larger than the bufferSize while zerocoding. |
286 | // Remove the MSG_ZEROCODED flag and send the unencoded data | 294 | // Remove the MSG_ZEROCODED flag and send the unencoded data |
287 | // instead | 295 | // instead |
288 | m_log.Debug("[LLUDPSERVER]: Packet exceeded buffer size during zerocoding for " + type + ". Removing MSG_ZEROCODED flag"); | 296 | m_log.Debug("[LLUDPSERVER]: Packet exceeded buffer size during zerocoding for " + type + ". DataLength=" + dataLength + |
297 | " and BufferLength=" + buffer.Data.Length + ". Removing MSG_ZEROCODED flag"); | ||
289 | data[0] = (byte)(data[0] & ~Helpers.MSG_ZEROCODED); | 298 | data[0] = (byte)(data[0] & ~Helpers.MSG_ZEROCODED); |
290 | Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength); | ||
291 | } | 299 | } |
292 | } | 300 | } |
293 | else | 301 | |
302 | // If the packet data wasn't already copied during zerocoding, copy it now | ||
303 | if (doCopy) | ||
294 | { | 304 | { |
295 | Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength); | 305 | if (dataLength <= buffer.Data.Length) |
306 | { | ||
307 | Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength); | ||
308 | } | ||
309 | else | ||
310 | { | ||
311 | m_log.Error("[LLUDPSERVER]: Packet exceeded buffer size! This could be an indication of packet assembly not obeying the MTU. Type=" + | ||
312 | type + ", DataLength=" + dataLength + ", BufferLength=" + buffer.Data.Length + ". Dropping packet"); | ||
313 | return; | ||
314 | } | ||
296 | } | 315 | } |
316 | |||
297 | buffer.DataLength = dataLength; | 317 | buffer.DataLength = dataLength; |
298 | 318 | ||
299 | #region Queue or Send | 319 | #region Queue or Send |
300 | 320 | ||
301 | // Look up the UDPClient this is going to | ||
302 | OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category); | 321 | OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category); |
303 | 322 | ||
304 | if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket)) | 323 | if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket)) |
@@ -513,7 +532,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
513 | IClientAPI client; | 532 | IClientAPI client; |
514 | if (!m_scene.ClientManager.TryGetValue(address, out client) || !(client is LLClientView)) | 533 | if (!m_scene.ClientManager.TryGetValue(address, out client) || !(client is LLClientView)) |
515 | { | 534 | { |
516 | m_log.Warn("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + | 535 | m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + |
517 | " in " + m_scene.RegionInfo.RegionName + ", currently tracking " + m_scene.ClientManager.Count + " clients"); | 536 | " in " + m_scene.RegionInfo.RegionName + ", currently tracking " + m_scene.ClientManager.Count + " clients"); |
518 | return; | 537 | return; |
519 | } | 538 | } |
@@ -568,9 +587,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
568 | // client.BytesSinceLastACK. Lockless thread safety | 587 | // client.BytesSinceLastACK. Lockless thread safety |
569 | int bytesSinceLastACK = Interlocked.Exchange(ref udpClient.BytesSinceLastACK, 0); | 588 | int bytesSinceLastACK = Interlocked.Exchange(ref udpClient.BytesSinceLastACK, 0); |
570 | bytesSinceLastACK += buffer.DataLength; | 589 | bytesSinceLastACK += buffer.DataLength; |
571 | if (bytesSinceLastACK > Packet.MTU * 2) | 590 | if (bytesSinceLastACK > LLUDPServer.MTU * 2) |
572 | { | 591 | { |
573 | bytesSinceLastACK -= Packet.MTU * 2; | 592 | bytesSinceLastACK -= LLUDPServer.MTU * 2; |
574 | SendAcks(udpClient); | 593 | SendAcks(udpClient); |
575 | } | 594 | } |
576 | Interlocked.Add(ref udpClient.BytesSinceLastACK, bytesSinceLastACK); | 595 | Interlocked.Add(ref udpClient.BytesSinceLastACK, bytesSinceLastACK); |