aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs39
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);