chronoxor / NetCoreServer

Ultra fast and low latency asynchronous socket server & client C# .NET Core library with support TCP, SSL, UDP, HTTP, HTTPS, WebSocket protocols and 10K connections problem solution
https://chronoxor.github.io/NetCoreServer
MIT License
2.63k stars 550 forks source link

Unhandled exception in WebSocket #279

Open ilsnk opened 8 months ago

ilsnk commented 8 months ago

At random time we have this:

Unhandled exception. System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values. (Parameter 'length')
   at System.Runtime.CompilerServices.RuntimeHelpers.GetSubArray[T](T[] array, Range range)
   at NetCoreServer.WebSocket.PrepareReceiveFrame(Byte[] buffer, Int64 offset, Int64 size) in /src/websocket-server/NetCoreServer/WebSocket.cs:line 323
   at NetCoreServer.TcpSession.ProcessReceive(SocketAsyncEventArgs e) in /src/websocket-server/NetCoreServer/TcpSession.cs:line 624
   at NetCoreServer.TcpSession.OnAsyncCompleted(Object sender, SocketAsyncEventArgs e) in /src/websocket-server/NetCoreServer/TcpSession.cs:line 567
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Net.Sockets.SocketAsyncEngine.System.Threading.IThreadPoolWorkItem.Execute()
   at System.Threading.ThreadPoolWorkQueue.Dispatch()
   at System.Threading.PortableThreadPool.WorkerThread.WorkerThreadStart()
ilsnk commented 8 months ago

We use latest library version

selmanahatli commented 6 months ago

I have same problem with 7.0.0 version. Is there any progress about this issue? Or could yo fix that in a different way? @ilsnk

suleymanbyzt commented 6 months ago

Same problem any update ?

ilsnk commented 6 months ago

We have not yet had time to independently study this problem. We are still getting this error.

suleymanbyzt commented 6 months ago

I still keep getting this error. How can I handle this? @chronoxor

Unhandled exception. System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values. (Parameter 'length') at NetCoreServer.WebSocket.PrepareReceiveFrame(Byte[] buffer, Int64 offset, Int64 size) at NetCoreServer.TcpSession.ProcessReceive(SocketAsyncEventArgs e) at NetCoreServer.TcpSession.OnAsyncCompleted(Object sender, SocketAsyncEventArgs e) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)

thank you for your help in advance

MrVitaly commented 5 months ago

@ilsnk , @selmanahatli, @suleymanbyzt, do you have a stable way to reproduce it?

chronoxor commented 5 months ago

It'll great if we can reproduce it and try to fix. I cannot reproduce this on my side. And we have WebSockets server on production running for months without issues.

ilsnk commented 5 months ago

Maybe we are not using the server implementation correctly? We have NetCoreServer acting as a socket, sending/receiving messages through our own abstract handlers.

ilsnk commented 5 months ago

We can assume that the problem may be in this code. Processing goes ProcessReceive is executed by asynchronous callback, lock is executed in OnRecieve. But since the callback (ProcessReceive) is executed from asynchronous callback code, by executing Resize we ignore the lock object

TspSession.cs:602, WebSocket.cs:322

What do you think?

image_2024-03-24_03-08-27

chronoxor commented 5 months ago

Still not reproduced on my side.

For each session receive buffer resize _receiveBuffer.Reserve(size + 1); should be called after OnReceived(_receiveBuffer.Data, 0, size) -> WebSocket.PrepareReceiveFrame(buffer, offset, size) -> lock (WsReceiveLock) { ... } is executed, so the buffer should be still valid in PrepareReceiveFrame.

daigs commented 5 months ago

今天我也出现这个bug了,导致我的服务程序直接结束进程了. 我是刚开机时(服务程序加入了开机自动启动),马上打开浏览器通过网页请求我的服务出现问题的, 当时在网页上点击按钮请求服务时卡主了一会儿,然后我就使劲点了几下按钮继续请求,然后就弹出异常窗口后服务程序挂掉了... 然后我就重启我的服务程序,但是无论如何也出现不了这种异常了... 我重写了OnReceived如何用try...catch捕获异常,防止我的服务程序挂掉 image image

ilsnk commented 4 months ago

Perhaps due to an incorrect shift of payload bytes? I'm not sure what exactly the crash error is coming from, but is it worth rechecking this code?

https://github.com/chronoxor/NetCoreServer/blob/51d182341f3234367a5ef440ffb72d393a8a5f81/source/NetCoreServer/WebSocket.cs#L412

image
ilsnk commented 2 weeks ago

@chronoxor I replaced your implementation with kestrel, and started catching this error on my server; Handled exception looks like:

System.Net.WebSockets.WebSocketException (0x80004005): The WebSocket received a frame with one or more reserved bits set.
   at System.Net.WebSockets.ManagedWebSocket.CloseWithReceiveErrorAndThrowAsync(WebSocketCloseStatus closeStatus, WebSocketError error, String errorMessage, Exception innerException)
   at System.Net.WebSockets.ManagedWebSocket.ReceiveAsyncPrivate[TResult](Memory`1 payloadBuffer, CancellationToken cancellationToken)
   at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource<TResult>.GetResult(Int16 token)
   at System.Threading.Tasks.ValueTask`1.ValueTaskSourceAsTask.<>c.<.cctor>b__4_0(Object state)

The frequency of this error coincides with the frequency of crashes of this thread. I understand that most likely the problem is in my client (which sends a broken frame). I still do not have a clear reproducing, only guesses.

In any case, you need to fix this error - otherwise it may be a planned DDoS servers made with NetCoreServer.