diff options
4 files changed, 53 insertions, 42 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs index e0cca05..fca7943 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs | |||
@@ -650,6 +650,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
650 | // leaving a dequeued packet still waiting to be sent out. Try to | 650 | // leaving a dequeued packet still waiting to be sent out. Try to |
651 | // send it again | 651 | // send it again |
652 | OutgoingPacket nextPacket = m_nextPackets[i]; | 652 | OutgoingPacket nextPacket = m_nextPackets[i]; |
653 | if(nextPacket.Buffer == null) | ||
654 | { | ||
655 | if (m_packetOutboxes[i].Count < 5) | ||
656 | emptyCategories |= CategoryToFlag(i); | ||
657 | continue; | ||
658 | } | ||
653 | if (bucket.RemoveTokens(nextPacket.Buffer.DataLength)) | 659 | if (bucket.RemoveTokens(nextPacket.Buffer.DataLength)) |
654 | { | 660 | { |
655 | // Send the packet | 661 | // Send the packet |
@@ -681,21 +687,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
681 | { | 687 | { |
682 | // A packet was pulled off the queue. See if we have | 688 | // A packet was pulled off the queue. See if we have |
683 | // enough tokens in the bucket to send it out | 689 | // enough tokens in the bucket to send it out |
684 | if (bucket.RemoveTokens(packet.Buffer.DataLength)) | 690 | if(packet.Buffer == null) |
685 | { | 691 | { |
686 | // Send the packet | 692 | // packet canceled elsewhere (by a ack for example) |
687 | m_udpServer.SendPacketFinal(packet); | ||
688 | packetSent = true; | ||
689 | |||
690 | if (queue.Count < 5) | 693 | if (queue.Count < 5) |
691 | emptyCategories |= CategoryToFlag(i); | 694 | emptyCategories |= CategoryToFlag(i); |
692 | } | 695 | } |
693 | else | 696 | else |
694 | { | 697 | { |
695 | // Save the dequeued packet for the next iteration | 698 | if (bucket.RemoveTokens(packet.Buffer.DataLength)) |
696 | m_nextPackets[i] = packet; | 699 | { |
700 | // Send the packet | ||
701 | m_udpServer.SendPacketFinal(packet); | ||
702 | packetSent = true; | ||
703 | |||
704 | if (queue.Count < 5) | ||
705 | emptyCategories |= CategoryToFlag(i); | ||
706 | } | ||
707 | else | ||
708 | { | ||
709 | // Save the dequeued packet for the next iteration | ||
710 | m_nextPackets[i] = packet; | ||
711 | } | ||
697 | } | 712 | } |
698 | |||
699 | } | 713 | } |
700 | else | 714 | else |
701 | { | 715 | { |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index ba5a2f3..d324623 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | |||
@@ -983,7 +983,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
983 | { | 983 | { |
984 | LLUDPClient udpClient = client.UDPClient; | 984 | LLUDPClient udpClient = client.UDPClient; |
985 | 985 | ||
986 | if (!udpClient.IsConnected) | 986 | if (!client.IsActive || !udpClient.IsConnected) |
987 | return; | 987 | return; |
988 | 988 | ||
989 | // Disconnect an agent if no packets are received for some time | 989 | // Disconnect an agent if no packets are received for some time |
@@ -1053,14 +1053,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1053 | internal void SendPacketFinal(OutgoingPacket outgoingPacket) | 1053 | internal void SendPacketFinal(OutgoingPacket outgoingPacket) |
1054 | { | 1054 | { |
1055 | UDPPacketBuffer buffer = outgoingPacket.Buffer; | 1055 | UDPPacketBuffer buffer = outgoingPacket.Buffer; |
1056 | if(buffer == null) // canceled packet | ||
1057 | return; | ||
1058 | LLUDPClient udpClient = outgoingPacket.Client; | ||
1059 | if (!udpClient.IsConnected) | ||
1060 | return; | ||
1061 | |||
1056 | byte flags = buffer.Data[0]; | 1062 | byte flags = buffer.Data[0]; |
1057 | bool isResend = (flags & Helpers.MSG_RESENT) != 0; | 1063 | bool isResend = (flags & Helpers.MSG_RESENT) != 0; |
1058 | bool isReliable = (flags & Helpers.MSG_RELIABLE) != 0; | 1064 | bool isReliable = (flags & Helpers.MSG_RELIABLE) != 0; |
1059 | bool isZerocoded = (flags & Helpers.MSG_ZEROCODED) != 0; | 1065 | bool isZerocoded = (flags & Helpers.MSG_ZEROCODED) != 0; |
1060 | LLUDPClient udpClient = outgoingPacket.Client; | ||
1061 | |||
1062 | if (!udpClient.IsConnected) | ||
1063 | return; | ||
1064 | 1066 | ||
1065 | int dataLength = buffer.DataLength; | 1067 | int dataLength = buffer.DataLength; |
1066 | 1068 | ||
@@ -1916,7 +1918,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1916 | { | 1918 | { |
1917 | Scene.ThreadAlive(2); | 1919 | Scene.ThreadAlive(2); |
1918 | 1920 | ||
1919 | |||
1920 | try | 1921 | try |
1921 | { | 1922 | { |
1922 | m_packetSent = false; | 1923 | m_packetSent = false; |
@@ -1971,7 +1972,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1971 | } | 1972 | } |
1972 | else if (!m_packetSent) | 1973 | else if (!m_packetSent) |
1973 | // Thread.Sleep((int)TickCountResolution); outch this is bad on linux | 1974 | // Thread.Sleep((int)TickCountResolution); outch this is bad on linux |
1974 | Thread.Sleep(15); // match the 16ms of windows7, dont ask 16 or win may decide to do 32ms. | 1975 | Thread.Sleep(15); // match the 16ms of windows, dont ask 16 or win may decide to do 32ms. |
1975 | 1976 | ||
1976 | Watchdog.UpdateThread(); | 1977 | Watchdog.UpdateThread(); |
1977 | } | 1978 | } |
@@ -1995,14 +1996,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1995 | 1996 | ||
1996 | if (udpClient.IsConnected) | 1997 | if (udpClient.IsConnected) |
1997 | { | 1998 | { |
1998 | if (m_resendUnacked) | 1999 | if (client.IsActive && m_resendUnacked) |
1999 | HandleUnacked(llClient); | 2000 | HandleUnacked(llClient); |
2000 | 2001 | ||
2001 | if (m_sendAcks) | 2002 | if (client.IsActive) |
2002 | SendAcks(udpClient); | 2003 | { |
2004 | if (m_sendAcks) | ||
2005 | SendAcks(udpClient); | ||
2003 | 2006 | ||
2004 | if (m_sendPing) | 2007 | if (m_sendPing) |
2005 | SendPing(udpClient); | 2008 | SendPing(udpClient); |
2009 | } | ||
2006 | 2010 | ||
2007 | // Dequeue any outgoing packets that are within the throttle limits | 2011 | // Dequeue any outgoing packets that are within the throttle limits |
2008 | if (udpClient.DequeueOutgoing()) | 2012 | if (udpClient.DequeueOutgoing()) |
@@ -2015,7 +2019,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2015 | m_log.Error( | 2019 | m_log.Error( |
2016 | string.Format("[LLUDPSERVER]: OutgoingPacketHandler iteration for {0} threw ", client.Name), ex); | 2020 | string.Format("[LLUDPSERVER]: OutgoingPacketHandler iteration for {0} threw ", client.Name), ex); |
2017 | } | 2021 | } |
2018 | client = null; | ||
2019 | } | 2022 | } |
2020 | 2023 | ||
2021 | #region Emergency Monitoring | 2024 | #region Emergency Monitoring |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs index 5fa4637..6f346d3 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs | |||
@@ -343,14 +343,12 @@ namespace OpenMetaverse | |||
343 | { | 343 | { |
344 | // kick off an async read | 344 | // kick off an async read |
345 | m_udpSocket.BeginReceiveFrom( | 345 | m_udpSocket.BeginReceiveFrom( |
346 | //wrappedBuffer.Instance.Data, | ||
347 | buf.Data, | 346 | buf.Data, |
348 | 0, | 347 | 0, |
349 | UDPPacketBuffer.BUFFER_SIZE, | 348 | buf.Data.Length, |
350 | SocketFlags.None, | 349 | SocketFlags.None, |
351 | ref buf.RemoteEndPoint, | 350 | ref buf.RemoteEndPoint, |
352 | AsyncEndReceive, | 351 | AsyncEndReceive, |
353 | //wrappedBuffer); | ||
354 | buf); | 352 | buf); |
355 | } | 353 | } |
356 | catch (SocketException e) | 354 | catch (SocketException e) |
@@ -364,14 +362,12 @@ namespace OpenMetaverse | |||
364 | try | 362 | try |
365 | { | 363 | { |
366 | m_udpSocket.BeginReceiveFrom( | 364 | m_udpSocket.BeginReceiveFrom( |
367 | //wrappedBuffer.Instance.Data, | ||
368 | buf.Data, | 365 | buf.Data, |
369 | 0, | 366 | 0, |
370 | UDPPacketBuffer.BUFFER_SIZE, | 367 | buf.Data.Length, |
371 | SocketFlags.None, | 368 | SocketFlags.None, |
372 | ref buf.RemoteEndPoint, | 369 | ref buf.RemoteEndPoint, |
373 | AsyncEndReceive, | 370 | AsyncEndReceive, |
374 | //wrappedBuffer); | ||
375 | buf); | 371 | buf); |
376 | salvaged = true; | 372 | salvaged = true; |
377 | } | 373 | } |
@@ -382,11 +378,6 @@ namespace OpenMetaverse | |||
382 | m_log.Warn("[UDPBASE]: Salvaged the UDP listener on port " + m_udpPort); | 378 | m_log.Warn("[UDPBASE]: Salvaged the UDP listener on port " + m_udpPort); |
383 | } | 379 | } |
384 | } | 380 | } |
385 | catch (ObjectDisposedException e) | ||
386 | { | ||
387 | m_log.Error( | ||
388 | string.Format("[UDPBASE]: Error processing UDP begin receive {0}. Exception ", UdpReceives), e); | ||
389 | } | ||
390 | catch (Exception e) | 381 | catch (Exception e) |
391 | { | 382 | { |
392 | m_log.Error( | 383 | m_log.Error( |
@@ -443,11 +434,6 @@ namespace OpenMetaverse | |||
443 | UdpReceives, se.ErrorCode), | 434 | UdpReceives, se.ErrorCode), |
444 | se); | 435 | se); |
445 | } | 436 | } |
446 | catch (ObjectDisposedException e) | ||
447 | { | ||
448 | m_log.Error( | ||
449 | string.Format("[UDPBASE]: Error processing UDP end receive {0}. Exception ", UdpReceives), e); | ||
450 | } | ||
451 | catch (Exception e) | 437 | catch (Exception e) |
452 | { | 438 | { |
453 | m_log.Error( | 439 | m_log.Error( |
@@ -502,6 +488,8 @@ namespace OpenMetaverse | |||
502 | */ | 488 | */ |
503 | public void SyncSend(UDPPacketBuffer buf) | 489 | public void SyncSend(UDPPacketBuffer buf) |
504 | { | 490 | { |
491 | if(buf.RemoteEndPoint == null) | ||
492 | return; // was already expired | ||
505 | try | 493 | try |
506 | { | 494 | { |
507 | m_udpSocket.SendTo( | 495 | m_udpSocket.SendTo( |
@@ -515,7 +503,7 @@ namespace OpenMetaverse | |||
515 | } | 503 | } |
516 | catch (SocketException e) | 504 | catch (SocketException e) |
517 | { | 505 | { |
518 | m_log.Warn("[UDPBASE]: sync send SocketException {0} " + e.Message); | 506 | m_log.WarnFormat("[UDPBASE]: sync send SocketException {0} {1}", buf.RemoteEndPoint, e.Message); |
519 | } | 507 | } |
520 | catch (ObjectDisposedException) { } | 508 | catch (ObjectDisposedException) { } |
521 | } | 509 | } |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs b/OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs index e0eee53..1f978e1 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs | |||
@@ -189,8 +189,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
189 | // Process all the pending adds | 189 | // Process all the pending adds |
190 | OutgoingPacket pendingAdd; | 190 | OutgoingPacket pendingAdd; |
191 | while (m_pendingAdds.TryDequeue(out pendingAdd)) | 191 | while (m_pendingAdds.TryDequeue(out pendingAdd)) |
192 | { | ||
192 | if (pendingAdd != null) | 193 | if (pendingAdd != null) |
193 | m_packets[pendingAdd.SequenceNumber] = pendingAdd; | 194 | m_packets[pendingAdd.SequenceNumber] = pendingAdd; |
195 | } | ||
194 | 196 | ||
195 | // Process all the pending removes, including updating statistics and round-trip times | 197 | // Process all the pending removes, including updating statistics and round-trip times |
196 | PendingAck pendingAcknowledgement; | 198 | PendingAck pendingAcknowledgement; |
@@ -203,15 +205,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
203 | if (ackedPacket != null) | 205 | if (ackedPacket != null) |
204 | { | 206 | { |
205 | m_packets.Remove(pendingAcknowledgement.SequenceNumber); | 207 | m_packets.Remove(pendingAcknowledgement.SequenceNumber); |
208 | |||
209 | // Update stats | ||
210 | Interlocked.Add(ref ackedPacket.Client.UnackedBytes, -ackedPacket.Buffer.DataLength); | ||
211 | |||
206 | ackedPacket.Client.FreeUDPBuffer(ackedPacket.Buffer); | 212 | ackedPacket.Client.FreeUDPBuffer(ackedPacket.Buffer); |
213 | ackedPacket.Buffer = null; | ||
207 | 214 | ||
208 | // As with other network applications, assume that an acknowledged packet is an | 215 | // As with other network applications, assume that an acknowledged packet is an |
209 | // indication that the network can handle a little more load, speed up the transmission | 216 | // indication that the network can handle a little more load, speed up the transmission |
210 | ackedPacket.Client.FlowThrottle.AcknowledgePackets(1); | 217 | ackedPacket.Client.FlowThrottle.AcknowledgePackets(1); |
211 | 218 | ||
212 | // Update stats | ||
213 | Interlocked.Add(ref ackedPacket.Client.UnackedBytes, -ackedPacket.Buffer.DataLength); | ||
214 | |||
215 | if (!pendingAcknowledgement.FromResend) | 219 | if (!pendingAcknowledgement.FromResend) |
216 | { | 220 | { |
217 | // Calculate the round-trip time for this packet and its ACK | 221 | // Calculate the round-trip time for this packet and its ACK |
@@ -242,10 +246,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
242 | if (removedPacket != null) | 246 | if (removedPacket != null) |
243 | { | 247 | { |
244 | m_packets.Remove(pendingRemove); | 248 | m_packets.Remove(pendingRemove); |
245 | removedPacket.Client.FreeUDPBuffer(removedPacket.Buffer); | ||
246 | 249 | ||
247 | // Update stats | 250 | // Update stats |
248 | Interlocked.Add(ref removedPacket.Client.UnackedBytes, -removedPacket.Buffer.DataLength); | 251 | Interlocked.Add(ref removedPacket.Client.UnackedBytes, -removedPacket.Buffer.DataLength); |
252 | |||
253 | removedPacket.Client.FreeUDPBuffer(removedPacket.Buffer); | ||
254 | removedPacket.Buffer = null; | ||
249 | } | 255 | } |
250 | } | 256 | } |
251 | } | 257 | } |