From 465a931c05b197f9d24688d13618475115fe97a5 Mon Sep 17 00:00:00 2001 From: Justin Clarke Casey Date: Fri, 31 Oct 2008 19:41:07 +0000 Subject: * In the client stack, if the BeginReceive() throws an exception then do print this out to the log once * This may help us detect if mysterious UDP disconnects are happening because of this. * Shouldn't be any functional change but I would appreciate a buddy check from Teravus if he has time (as for all client stack changes) --- .../Region/ClientStack/LindenUDP/LLUDPServer.cs | 103 ++++++++++----------- 1 file changed, 49 insertions(+), 54 deletions(-) (limited to 'OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index 40b4a42..52a2467 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs @@ -271,17 +271,59 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_socket.BeginReceiveFrom( RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref reusedEpSender, ReceivedData, null); } - catch (SocketException) + catch (SocketException e) { - // We don't need to see this error, reset connection and get next UDP packet off the buffer - // If the UDP packet is part of the same stream, this will happen several hundreds of times before - // the next set of UDP data is for a valid client. - //m_log.ErrorFormat("[CLIENT]: BeginRecieve threw exception " + e.Message + ": " + e.StackTrace ); - // ENDLESS LOOP ON PURPOSE! - ResetEndPoint(); + // Reset connection and get next UDP packet off the buffer + // If the UDP packet is part of the same stream, this will happen several hundreds of times before + // the next set of UDP data is for a valid client. + ResetServerEndPoint(e); } } + + /// + /// Reset the server endpoint + /// + /// + /// The exception that has triggered the reset. Can be null if there was no exception. + /// + private void ResetServerEndPoint(Exception e) + { + try + { + CloseCircuit(reusedEpSender, e); + } + catch (Exception a) + { + m_log.Error("[UDPSERVER]: " + a); + } + + // ENDLESS LOOP ON PURPOSE! + // We need to purge the UDP stream of crap from the client that disconnected nastily or the UDP server will die + // The only way to do that is to beginreceive again! + BeginReceive(); + } + + /// + /// Close a client circuit. This is done in response to an exception on receive, and should not be called + /// normally. + /// + /// + /// The exception that caused the close. Can be null if there was no exception + private void CloseCircuit(EndPoint sender, Exception e) + { + uint circuit; + lock (clientCircuits) + { + if (clientCircuits.TryGetValue(sender, out circuit)) + { + m_packetServer.CloseCircuit(circuit); + + if (e != null) + m_log.ErrorFormat("[CLIENT]: Closed circuit {0} {1} due to exception {2}", circuit, sender, e); + } + } + } /// /// Finish the process of asynchronously receiving the next bit of raw data @@ -327,53 +369,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP return hasReceivedOkay; } - private void ResetEndPoint() - { - try - { - CloseEndPoint(reusedEpSender); - } - catch (Exception a) - { - m_log.Error("[UDPSERVER]: " + a); - } - - // ENDLESS LOOP ON PURPOSE! - - // We need to purge the UDP stream of crap from the client that disconnected nastily or the UDP server will die - // The only way to do that is to beginreceive again! - BeginReceive(); - - try - { - // m_socket.BeginReceiveFrom( - // RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref reusedEpSender, ReceivedData, null); - - // Ter: For some stupid reason ConnectionReset basically kills our async event structure.. - // so therefore.. we've got to tell the server to BeginReceiveFrom again. - // This will happen over and over until we've gone through all packets - // sent to and from this particular user. - // Stupid I know.. - // but Flusing the buffer would be even more stupid... so, we're stuck with this ugly method. - } - catch (SocketException e) - { - m_log.DebugFormat("[UDPSERVER]: Exception {0} : {1}", e.Message, e.StackTrace ); - } - } - - private void CloseEndPoint(EndPoint sender) - { - uint circuit; - lock (clientCircuits) - { - if (clientCircuits.TryGetValue(sender, out circuit)) - { - m_packetServer.CloseCircuit(circuit); - } - } - } - /// /// Add a new client circuit. /// -- cgit v1.1