diff options
author | John Hurliman | 2009-10-13 18:56:54 -0700 |
---|---|---|
committer | John Hurliman | 2009-10-13 18:56:54 -0700 |
commit | e8c1e69a0dbab1a7db894eeff6b052bbd350a8f5 (patch) | |
tree | 6d29a3bae418c1c5a06e3f1b8ad4a59db57a8d9e /OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs | |
parent | * Consolidated adding / removing ClientManager IClientAPIs to two places in S... (diff) | |
download | opensim-SC-e8c1e69a0dbab1a7db894eeff6b052bbd350a8f5.zip opensim-SC-e8c1e69a0dbab1a7db894eeff6b052bbd350a8f5.tar.gz opensim-SC-e8c1e69a0dbab1a7db894eeff6b052bbd350a8f5.tar.bz2 opensim-SC-e8c1e69a0dbab1a7db894eeff6b052bbd350a8f5.tar.xz |
* Copied LocklessQueue.cs into OpenSim.Framework and added the .Count property and .Clear() method
* Changed the way the QueueEmpty callback is fired. It will be fired asynchronously as soon as an empty queue is detected (this can happen immediately following a dequeue), and will not be fired again until at least one packet is dequeued from that queue. This will give callbacks advanced notice of an empty queue and prevent callbacks from stacking up while the queue is empty
* Added LLUDPClient.IsConnected checks in several places to prevent unwanted network activity after a client disconnects
* Prevent LLClientView.Close() from being called twice every disconnect
* Removed the packet resend limit and improved the client timeout check
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs | 107 |
1 files changed, 48 insertions, 59 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index 8689af3..57fee59 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs | |||
@@ -332,8 +332,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
332 | 332 | ||
333 | public void ResendUnacked(LLUDPClient udpClient) | 333 | public void ResendUnacked(LLUDPClient udpClient) |
334 | { | 334 | { |
335 | if (udpClient.NeedAcks.Count > 0) | 335 | if (udpClient.IsConnected && udpClient.NeedAcks.Count > 0) |
336 | { | 336 | { |
337 | // Disconnect an agent if no packets are received for some time | ||
338 | //FIXME: Make 60 an .ini setting | ||
339 | if (Environment.TickCount - udpClient.TickLastPacketReceived > 1000 * 60) | ||
340 | { | ||
341 | m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + udpClient.AgentID); | ||
342 | |||
343 | RemoveClient(udpClient); | ||
344 | return; | ||
345 | } | ||
346 | |||
347 | // Get a list of all of the packets that have been sitting unacked longer than udpClient.RTO | ||
337 | List<OutgoingPacket> expiredPackets = udpClient.NeedAcks.GetExpiredPackets(udpClient.RTO); | 348 | List<OutgoingPacket> expiredPackets = udpClient.NeedAcks.GetExpiredPackets(udpClient.RTO); |
338 | 349 | ||
339 | if (expiredPackets != null) | 350 | if (expiredPackets != null) |
@@ -343,48 +354,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
343 | { | 354 | { |
344 | OutgoingPacket outgoingPacket = expiredPackets[i]; | 355 | OutgoingPacket outgoingPacket = expiredPackets[i]; |
345 | 356 | ||
346 | // FIXME: Make this an .ini setting | 357 | //m_log.DebugFormat("[LLUDPSERVER]: Resending packet #{0} (attempt {1}), {2}ms have passed", |
347 | if (outgoingPacket.ResendCount < 3) | 358 | // outgoingPacket.SequenceNumber, outgoingPacket.ResendCount, Environment.TickCount - outgoingPacket.TickCount); |
348 | { | ||
349 | //Logger.Debug(String.Format("Resending packet #{0} (attempt {1}), {2}ms have passed", | ||
350 | // outgoingPacket.SequenceNumber, outgoingPacket.ResendCount, Environment.TickCount - outgoingPacket.TickCount)); | ||
351 | 359 | ||
352 | // Set the resent flag | 360 | // Set the resent flag |
353 | outgoingPacket.Buffer.Data[0] = (byte)(outgoingPacket.Buffer.Data[0] | Helpers.MSG_RESENT); | 361 | outgoingPacket.Buffer.Data[0] = (byte)(outgoingPacket.Buffer.Data[0] | Helpers.MSG_RESENT); |
354 | outgoingPacket.Category = ThrottleOutPacketType.Resend; | 362 | outgoingPacket.Category = ThrottleOutPacketType.Resend; |
355 | 363 | ||
356 | // The TickCount will be set to the current time when the packet | 364 | // The TickCount will be set to the current time when the packet |
357 | // is actually sent out again | 365 | // is actually sent out again |
358 | outgoingPacket.TickCount = 0; | 366 | outgoingPacket.TickCount = 0; |
359 | 367 | ||
360 | // Bump up the resend count on this packet | 368 | // Bump up the resend count on this packet |
361 | Interlocked.Increment(ref outgoingPacket.ResendCount); | 369 | Interlocked.Increment(ref outgoingPacket.ResendCount); |
362 | //Interlocked.Increment(ref Stats.ResentPackets); | 370 | //Interlocked.Increment(ref Stats.ResentPackets); |
363 | 371 | ||
364 | // Queue or (re)send the packet | 372 | // Requeue or resend the packet |
365 | if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket)) | 373 | if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket)) |
366 | SendPacketFinal(outgoingPacket); | 374 | SendPacketFinal(outgoingPacket); |
367 | } | ||
368 | else | ||
369 | { | ||
370 | m_log.DebugFormat("[LLUDPSERVER]: Dropping packet #{0} for agent {1} after {2} failed attempts", | ||
371 | outgoingPacket.SequenceNumber, outgoingPacket.Client.RemoteEndPoint, outgoingPacket.ResendCount); | ||
372 | |||
373 | lock (udpClient.NeedAcks.SyncRoot) | ||
374 | udpClient.NeedAcks.RemoveUnsafe(outgoingPacket.SequenceNumber); | ||
375 | |||
376 | //Interlocked.Increment(ref Stats.DroppedPackets); | ||
377 | |||
378 | // Disconnect an agent if no packets are received for some time | ||
379 | //FIXME: Make 60 an .ini setting | ||
380 | if (Environment.TickCount - udpClient.TickLastPacketReceived > 1000 * 60) | ||
381 | { | ||
382 | m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + udpClient.AgentID); | ||
383 | |||
384 | RemoveClient(udpClient); | ||
385 | return; | ||
386 | } | ||
387 | } | ||
388 | } | 375 | } |
389 | } | 376 | } |
390 | } | 377 | } |
@@ -403,6 +390,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
403 | bool isReliable = (flags & Helpers.MSG_RELIABLE) != 0; | 390 | bool isReliable = (flags & Helpers.MSG_RELIABLE) != 0; |
404 | LLUDPClient udpClient = outgoingPacket.Client; | 391 | LLUDPClient udpClient = outgoingPacket.Client; |
405 | 392 | ||
393 | if (!udpClient.IsConnected) | ||
394 | return; | ||
395 | |||
406 | // Keep track of when this packet was sent out (right now) | 396 | // Keep track of when this packet was sent out (right now) |
407 | outgoingPacket.TickCount = Environment.TickCount; | 397 | outgoingPacket.TickCount = Environment.TickCount; |
408 | 398 | ||
@@ -481,14 +471,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
481 | } | 471 | } |
482 | catch (MalformedDataException) | 472 | catch (MalformedDataException) |
483 | { | 473 | { |
484 | m_log.ErrorFormat("[LLUDPSERVER]: Malformed data, cannot parse packet:\n{0}", | 474 | m_log.ErrorFormat("[LLUDPSERVER]: Malformed data, cannot parse packet from {0}:\n{1}", |
485 | Utils.BytesToHexString(buffer.Data, buffer.DataLength, null)); | 475 | buffer.RemoteEndPoint, Utils.BytesToHexString(buffer.Data, buffer.DataLength, null)); |
486 | } | 476 | } |
487 | 477 | ||
488 | // Fail-safe check | 478 | // Fail-safe check |
489 | if (packet == null) | 479 | if (packet == null) |
490 | { | 480 | { |
491 | m_log.Warn("[LLUDPSERVER]: Couldn't build a message from the incoming data"); | 481 | m_log.Warn("[LLUDPSERVER]: Couldn't build a message from incoming data " + buffer.DataLength + |
482 | " bytes long from " + buffer.RemoteEndPoint); | ||
492 | return; | 483 | return; |
493 | } | 484 | } |
494 | 485 | ||
@@ -513,6 +504,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
513 | 504 | ||
514 | udpClient = ((LLClientView)client).UDPClient; | 505 | udpClient = ((LLClientView)client).UDPClient; |
515 | 506 | ||
507 | if (!udpClient.IsConnected) | ||
508 | return; | ||
509 | |||
516 | #endregion Packet to Client Mapping | 510 | #endregion Packet to Client Mapping |
517 | 511 | ||
518 | // Stats tracking | 512 | // Stats tracking |
@@ -643,7 +637,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
643 | // Create the LLClientView | 637 | // Create the LLClientView |
644 | LLClientView client = new LLClientView(remoteEndPoint, m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode); | 638 | LLClientView client = new LLClientView(remoteEndPoint, m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode); |
645 | client.OnLogout += LogoutHandler; | 639 | client.OnLogout += LogoutHandler; |
646 | client.OnConnectionClosed += ConnectionClosedHandler; | ||
647 | 640 | ||
648 | // Start the IClientAPI | 641 | // Start the IClientAPI |
649 | client.Start(); | 642 | client.Start(); |
@@ -745,17 +738,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
745 | { | 738 | { |
746 | LLUDPClient udpClient = ((LLClientView)client).UDPClient; | 739 | LLUDPClient udpClient = ((LLClientView)client).UDPClient; |
747 | 740 | ||
748 | if (udpClient.DequeueOutgoing()) | 741 | if (udpClient.IsConnected) |
749 | packetSent = true; | ||
750 | if (resendUnacked) | ||
751 | ResendUnacked(udpClient); | ||
752 | if (sendAcks) | ||
753 | { | 742 | { |
754 | SendAcks(udpClient); | 743 | if (udpClient.DequeueOutgoing()) |
755 | udpClient.SendPacketStats(); | 744 | packetSent = true; |
745 | if (resendUnacked) | ||
746 | ResendUnacked(udpClient); | ||
747 | if (sendAcks) | ||
748 | { | ||
749 | SendAcks(udpClient); | ||
750 | udpClient.SendPacketStats(); | ||
751 | } | ||
752 | if (sendPings) | ||
753 | SendPing(udpClient); | ||
756 | } | 754 | } |
757 | if (sendPings) | ||
758 | SendPing(udpClient); | ||
759 | } | 755 | } |
760 | } | 756 | } |
761 | ); | 757 | ); |
@@ -808,14 +804,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
808 | 804 | ||
809 | private void LogoutHandler(IClientAPI client) | 805 | private void LogoutHandler(IClientAPI client) |
810 | { | 806 | { |
811 | client.OnLogout -= LogoutHandler; | ||
812 | client.SendLogoutPacket(); | 807 | client.SendLogoutPacket(); |
813 | } | 808 | } |
814 | |||
815 | private void ConnectionClosedHandler(IClientAPI client) | ||
816 | { | ||
817 | client.OnConnectionClosed -= ConnectionClosedHandler; | ||
818 | RemoveClient(((LLClientView)client).UDPClient); | ||
819 | } | ||
820 | } | 809 | } |
821 | } | 810 | } |