From 477f0e230b6842b71c7af0c7ced09709dee5ca2a Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Fri, 10 Mar 2023 13:27:42 +0000 Subject: [PATCH] avoid a old potencial stack overflow --- .../ClientStack/Linden/UDP/OpenSimUDPBase.cs | 184 +++++++++--------- 1 file changed, 93 insertions(+), 91 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs index 19cfbbde23..96e0d5274a 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs @@ -328,114 +328,116 @@ namespace OpenMetaverse private void AsyncBeginReceive() { - if (!IsRunningInbound) - return; - - UDPPacketBuffer buf = GetNewUDPBuffer(new IPEndPoint(IPAddress.Any, 0)); // we need a fresh one here, for now at least - try + while(IsRunningInbound) { - // kick off an async read - m_udpSocket.BeginReceiveFrom( - buf.Data, - 0, - buf.Data.Length, - SocketFlags.None, - ref buf.RemoteEndPoint, - AsyncEndReceive, - buf); - } - catch (SocketException e) - { - if (e.SocketErrorCode == SocketError.ConnectionReset) + UDPPacketBuffer buf = GetNewUDPBuffer(new IPEndPoint(IPAddress.Any, 0)); // we need a fresh one here, for now at least + try { - m_log.Warn("[UDPBASE]: SIO_UDP_CONNRESET was ignored, attempting to salvage the UDP listener on port " + m_udpPort); - bool salvaged = false; - while (!salvaged) - { - try - { - m_udpSocket.BeginReceiveFrom( - buf.Data, - 0, - buf.Data.Length, - SocketFlags.None, - ref buf.RemoteEndPoint, - AsyncEndReceive, - buf); - salvaged = true; - } - catch (SocketException) { } - catch (ObjectDisposedException) { return; } - } + // kick off an async read + IAsyncResult iar = m_udpSocket.BeginReceiveFrom( + buf.Data, + 0, + buf.Data.Length, + SocketFlags.None, + ref buf.RemoteEndPoint, + AsyncEndReceive, + buf); - m_log.Warn("[UDPBASE]: Salvaged the UDP listener on port " + m_udpPort); + if (!iar.CompletedSynchronously) + return; + } + catch (SocketException e) + { + if (e.SocketErrorCode == SocketError.ConnectionReset) + { + m_log.Warn("[UDPBASE]: SIO_UDP_CONNRESET was ignored, attempting to salvage the UDP listener on port " + m_udpPort); + { + try + { + IAsyncResult iar = m_udpSocket.BeginReceiveFrom( + buf.Data, + 0, + buf.Data.Length, + SocketFlags.None, + ref buf.RemoteEndPoint, + AsyncEndReceive, + buf); + + if (!iar.CompletedSynchronously) + return; + } + catch (SocketException) { } + catch (ObjectDisposedException) { return; } + } + m_log.Warn("[UDPBASE]: Salvaged the UDP listener on port " + m_udpPort); + } + } + catch (Exception e) + { + m_log.Error( + string.Format("[UDPBASE]: Error processing UDP begin receive {0}. Exception ", UdpReceives), e); } - } - catch (Exception e) - { - m_log.Error( - string.Format("[UDPBASE]: Error processing UDP begin receive {0}. Exception ", UdpReceives), e); } } private void AsyncEndReceive(IAsyncResult iar) { - // Asynchronous receive operations will complete here through the call - // to AsyncBeginReceive - if (IsRunningInbound) + bool sync = iar.CompletedSynchronously; + try { + // get the buffer that was created in AsyncBeginReceive + // this is the received data + UDPPacketBuffer buffer = (UDPPacketBuffer)iar.AsyncState; + + int startTick = Util.EnvironmentTickCount(); + + // get the length of data actually read from the socket, store it with the + // buffer + buffer.DataLength = m_udpSocket.EndReceiveFrom(iar, ref buffer.RemoteEndPoint); + + if(!IsRunningInbound) + return; + UdpReceives++; - - try + + // call the abstract method PacketReceived(), passing the buffer that + // has just been filled from the socket read. + PacketReceived(buffer); + + // If more than one thread can be calling AsyncEndReceive() at once (e.g. if m_asyncPacketHandler) + // then a particular stat may be inaccurate due to a race condition. We won't worry about this + // since this should be rare and won't cause a runtime problem. + if (m_currentReceiveTimeSamples >= s_receiveTimeSamples) { - // get the buffer that was created in AsyncBeginReceive - // this is the received data - UDPPacketBuffer buffer = (UDPPacketBuffer)iar.AsyncState; + AverageReceiveTicksForLastSamplePeriod + = (float)m_receiveTicksInCurrentSamplePeriod / s_receiveTimeSamples; - int startTick = Util.EnvironmentTickCount(); - - // get the length of data actually read from the socket, store it with the - // buffer - buffer.DataLength = m_udpSocket.EndReceiveFrom(iar, ref buffer.RemoteEndPoint); - - // call the abstract method PacketReceived(), passing the buffer that - // has just been filled from the socket read. - PacketReceived(buffer); - - // If more than one thread can be calling AsyncEndReceive() at once (e.g. if m_asyncPacketHandler) - // then a particular stat may be inaccurate due to a race condition. We won't worry about this - // since this should be rare and won't cause a runtime problem. - if (m_currentReceiveTimeSamples >= s_receiveTimeSamples) - { - AverageReceiveTicksForLastSamplePeriod - = (float)m_receiveTicksInCurrentSamplePeriod / s_receiveTimeSamples; - - m_receiveTicksInCurrentSamplePeriod = 0; - m_currentReceiveTimeSamples = 0; - } - else - { - m_receiveTicksInCurrentSamplePeriod += Util.EnvironmentTickCountSubtract(startTick); - m_currentReceiveTimeSamples++; - } + m_receiveTicksInCurrentSamplePeriod = 0; + m_currentReceiveTimeSamples = 0; } - catch (SocketException se) + else { - m_log.Error( - string.Format( - "[UDPBASE]: Error processing UDP end receive {0}, socket error code {1}. Exception ", - UdpReceives, se.ErrorCode), - se); + m_receiveTicksInCurrentSamplePeriod += Util.EnvironmentTickCountSubtract(startTick); + m_currentReceiveTimeSamples++; } - catch (Exception e) - { - m_log.Error( - string.Format("[UDPBASE]: Error processing UDP end receive {0}. Exception ", UdpReceives), e); - } - finally - { + } + catch (SocketException se) + { + m_log.Error( + string.Format( + "[UDPBASE]: Error processing UDP end receive {0}, socket error code {1}. Exception ", + UdpReceives, se.ErrorCode), + se); + } + catch (Exception e) + { + m_log.Error( + string.Format("[UDPBASE]: Error processing UDP end receive {0}. Exception ", UdpReceives), e); + } + finally + { + if(IsRunningInbound && !sync) AsyncBeginReceive(); - } } }