From 6849f4566047cf358ffb42f9efcb90658f2be42d Mon Sep 17 00:00:00 2001 From: lbsa71 Date: Sat, 9 Aug 2008 05:26:33 +0000 Subject: * Shielded against various forms of Malformed data crashes - if there is an error in packet creation, we just log and ignore it * If there's a Socket.AlreadyInProgress, just silently ignore this one * Tried to refactor the Reset and BeginRecieve logic into something a little more readable, little less duplicated --- .../Region/ClientStack/LindenUDP/LLUDPServer.cs | 184 ++++++++------------- 1 file changed, 65 insertions(+), 119 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 b08b59d..6e9bca3 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs @@ -153,9 +153,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP int numBytes = 1; + bool ok = false; + try { numBytes = m_socket.EndReceiveFrom(result, ref epSender); + ok = true; } catch (SocketException e) { @@ -165,149 +168,52 @@ namespace OpenSim.Region.ClientStack.LindenUDP switch (e.SocketErrorCode) { case SocketError.AlreadyInProgress: + return; + case SocketError.NetworkReset: case SocketError.ConnectionReset: - try - { - CloseEndPoint(epSender); - } - catch (Exception a) - { - m_log.Info("[UDPSERVER]: " + a.ToString()); - } - try - { - m_socket.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, - 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) - { - } break; + default: - try - { - CloseEndPoint(epSender); - } - catch (Exception) - { - //m_log.Info("[UDPSERVER]" + a.ToString()); - } - try - { - m_socket.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, - 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 e2) - { - m_log.Error("[UDPSERVER]: " + e2.ToString()); - } - - // Here's some reference code! :D - // Shutdown and restart the UDP listener! hehe - // Shiny - - //Server.Shutdown(SocketShutdown.Both); - //CloseEndPoint(epSender); - //ServerListener(); - break; + throw; } - - //return; } catch (ObjectDisposedException e) { - m_log.Debug("[UDPSERVER]: " + e.ToString()); - try - { - m_socket.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, - 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 e2) - { - m_log.Error("[UDPSERVER]: " + e2.ToString()); - } - catch (ObjectDisposedException) - { - } - //return; + m_log.DebugFormat("ObjectDisposedException: Object {0} disposed.", e.ObjectName); + // Uhh, what object, and why? this needs better handling. } - //System.Console.WriteLine("UDPServer : recieved message from {0}", epSender.ToString()); - epProxy = epSender; - if (proxyPortOffset != 0) + if (ok) { - epSender = ProxyCodec.DecodeProxyMessage(RecvBuffer, ref numBytes); - } - - int packetEnd = numBytes - 1; + epProxy = epSender; + if (proxyPortOffset != 0) + { + epSender = ProxyCodec.DecodeProxyMessage(RecvBuffer, ref numBytes); + } - try - { - packet = PacketPool.Instance.GetPacket(RecvBuffer, ref packetEnd, ZeroBuffer); - } - catch (Exception e) - { - m_log.Debug("[UDPSERVER]: " + e.ToString()); - } + int packetEnd = numBytes - 1; - try - { - m_socket.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, ReceivedData, null); - } - catch (SocketException) - { try { - CloseEndPoint(epSender); + packet = PacketPool.Instance.GetPacket(RecvBuffer, ref packetEnd, ZeroBuffer); } - catch (Exception a) + catch (MalformedDataException e) { - m_log.Info("[UDPSERVER]: " + a.ToString()); + m_log.DebugFormat("Dropped Malformed Packet due to MalformedDataException: {0}", e.StackTrace); } - try + catch (IndexOutOfRangeException e) { - m_socket.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, - 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. + m_log.DebugFormat("Dropped Malformed Packet due to IndexOutOfRangeException: {0}", e.StackTrace); } - catch (SocketException e5) + catch (Exception e) { - m_log.Error("[UDPSERVER]: " + e5.ToString()); + m_log.Debug("[UDPSERVER]: " + e.ToString()); } } - catch (ObjectDisposedException) - { - } + BeginReceive(); + if (packet != null) { try @@ -360,7 +266,47 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } } + } + + private void BeginReceive() + { + try + { + m_socket.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, ReceivedData, null); + } + catch (SocketException) + { + ResetEndPoint(); + } + } + + private void ResetEndPoint() + { + try + { + CloseEndPoint(epSender); + } + catch (Exception a) + { + m_log.Info("[UDPSERVER]: " + a.ToString()); + } + try + { + m_socket.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, + 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) -- cgit v1.1