public void RecvFromCallback(IAsyncResult ar) { try { if (_remote == null) { return; } EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0); int bytesRead = _remote.EndReceiveFrom(ar, ref remoteEndPoint); byte[] dataOut = new byte[bytesRead]; int outlen; IEncryptor encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password); encryptor.DecryptUDP(_buffer, bytesRead, dataOut, out outlen); byte[] sendBuf = new byte[outlen + 3]; Array.Copy(dataOut, 0, sendBuf, 3, outlen); Logging.Debug(_localEndPoint, _remoteEndPoint, outlen, "UDP Relay"); _local?.SendTo(sendBuf, outlen + 3, 0, _localEndPoint); Receive(); } catch (ObjectDisposedException) { // TODO: handle the ObjectDisposedException } catch (Exception) { // TODO: need more think about handle other Exceptions, or should remove this catch(). } finally { // No matter success or failed, we keep receiving } }
public async Task Start(byte[] data, int length) { Interlocked.Exchange(ref _state, _running); SaeaAwaitable upSaea = null; SaeaAwaitable downSaea = null; try { Logging.Debug($"-----UDP relay got {length}-----"); IEncryptor encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password); byte[] dataIn = new byte[length - 3]; Array.Copy(data, 3, dataIn, 0, length - 3); upSaea = _argsPool.Rent(); int outlen; encryptor.EncryptUDP(dataIn, dataIn.Length, upSaea.Saea.Buffer, out outlen); upSaea.Saea.SetBuffer(0, outlen); upSaea.Saea.RemoteEndPoint = _serverEndPoint; var ret = await _serverSocket.SendToAsync(upSaea); if (ret != SocketError.Success) { Logging.Error($"[udp] remote sendto {ret},{upSaea.Saea.BytesTransferred}"); Close(); return; } Logging.Debug($"[udp] remote sendto {_localEndPoint} -> {_serverEndPoint} {upSaea.Saea.BytesTransferred}"); _argsPool.Return(upSaea); upSaea = null; while (IsRunning) { downSaea = _argsPool.Rent(); downSaea.Saea.RemoteEndPoint = new IPEndPoint(IPAddress.Any, 0); ret = await _serverSocket.ReceiveFromAsync(downSaea); var bytesReceived = downSaea.Saea.BytesTransferred; if (ret != SocketError.Success) { Logging.Error($"[udp] remote recvfrom {ret},{bytesReceived}"); Close(); return; } Logging.Debug($"[udp] remote recvfrom {downSaea.Saea.RemoteEndPoint} -> {_localSocket.LocalEndPoint} {bytesReceived}"); byte[] dataOut = new byte[bytesReceived]; encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password); encryptor.DecryptUDP(downSaea.Saea.Buffer, bytesReceived, dataOut, out outlen); downSaea.ClearAndResetSaeaProperties(); byte[] buf = downSaea.Saea.Buffer; buf[0] = buf[1] = buf[2] = 0; Array.Copy(dataOut, 0, buf, 3, outlen); downSaea.Saea.RemoteEndPoint = _localEndPoint; downSaea.Saea.SetBuffer(0, outlen + 3); ret = await _localSocket.SendToAsync(downSaea); if (ret != SocketError.Success) { Logging.Error($"[udp] local sendto {ret},{downSaea.Saea.BytesTransferred}"); Close(); return; } Logging.Debug($"[udp] local sendto {_localSocket.LocalEndPoint} -> {_localEndPoint} {downSaea.Saea.BytesTransferred}"); _argsPool.Return(downSaea); downSaea = null; } } catch (Exception e) { Logging.LogUsefulException(e); Close(); } finally { _argsPool.Return(upSaea); upSaea = null; _argsPool.Return(downSaea); downSaea = null; } }
public async Task Start(byte[] data, int length) { Interlocked.Exchange(ref _state, _running); SaeaAwaitable udpSaea = null; try { while (IsRunning) { IEncryptor encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password); byte[] dataIn = new byte[length - 3]; Array.Copy(data, 3, dataIn, 0, length - 3); udpSaea = _argsPool.Rent(); int outlen; encryptor.EncryptUDP(dataIn, length - 3, udpSaea.Saea.Buffer, out outlen); udpSaea.Saea.SetBuffer(0, outlen); udpSaea.Saea.RemoteEndPoint = _remoteEndPoint; Logging.Debug(_localEndPoint, _remoteEndPoint, outlen, "UDP Relay"); var ret = await _remote.SendToAsync(udpSaea); if (ret != SocketError.Success) { Close(); return; } udpSaea = _argsPool.Rent(); udpSaea.Saea.RemoteEndPoint = new IPEndPoint(IPAddress.Any, 0); ret = await _remote.ReceiveFromAsync(udpSaea); if (ret != SocketError.Success) { Close(); return; } var bytesReceived = udpSaea.Saea.BytesTransferred; Logging.Debug($"++++++Receive Server Port, size:" + bytesReceived); byte[] dataOut = new byte[bytesReceived]; encryptor = EncryptorFactory.GetEncryptor(_server.method, _server.password); encryptor.DecryptUDP(udpSaea.Saea.Buffer, bytesReceived, dataOut, out outlen); _argsPool.Return(udpSaea); udpSaea = null; udpSaea = _argsPool.Rent(); byte[] buf = udpSaea.Saea.Buffer; buf[0] = buf[1] = buf[2] = 0; Array.Copy(dataOut, 0, buf, 3, outlen); udpSaea.Saea.RemoteEndPoint = _localEndPoint; udpSaea.Saea.SetBuffer(0, outlen + 3); Logging.Debug(_localEndPoint, _remoteEndPoint, outlen, "UDP Relay"); ret = await _local.SendToAsync(udpSaea); if (ret != SocketError.Success) { Close(); return; } _argsPool.Return(udpSaea); udpSaea = null; } } catch (Exception e) { Logging.LogUsefulException(e); Close(); } finally { _argsPool.Return(udpSaea); udpSaea = null; } }