avoid a old potencial stack overflow

This commit is contained in:
UbitUmarov
2023-03-10 13:36:32 +00:00
parent 8a0778beaf
commit 99825acac0

View File

@@ -58,7 +58,7 @@ namespace OpenMetaverse
/// <summary>UDP socket, used in either client or server mode</summary>
private Socket m_udpSocket;
public static Object m_udpBuffersPoolLock = new Object();
public static Object m_udpBuffersPoolLock = new();
public static UDPPacketBuffer[] m_udpBuffersPool = new UDPPacketBuffer[1000];
public static int m_udpBuffersPoolPtr = -1;
@@ -322,157 +322,119 @@ 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)
{
UdpReceives++;
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);
// 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++;
}
}
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
{
AsyncBeginReceive();
}
}
}
/* not in use
public void AsyncBeginSend(UDPPacketBuffer buf)
{
// if (IsRunningOutbound)
// {
// This is strictly for debugging purposes to simulate dropped
// packets when testing throttles & retransmission code
// if (DropOutgoingPacket())
// return;
try
{
m_udpSocket.BeginSendTo(
buf.Data,
0,
buf.DataLength,
SocketFlags.None,
buf.RemoteEndPoint,
AsyncEndSend,
buf);
}
catch (SocketException) { }
catch (ObjectDisposedException) { }
// }
}
void AsyncEndSend(IAsyncResult result)
{
bool sync = iar.CompletedSynchronously;
try
{
// UDPPacketBuffer buf = (UDPPacketBuffer)result.AsyncState;
m_udpSocket.EndSendTo(result);
// get the buffer that was created in AsyncBeginReceive
// this is the received data
UDPPacketBuffer buffer = (UDPPacketBuffer)iar.AsyncState;
UdpSends++;
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++;
// 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++;
}
}
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();
}
catch (SocketException) { }
catch (ObjectDisposedException) { }
}
*/
public void SyncSend(UDPPacketBuffer buf)
{
if(buf.RemoteEndPoint == null)