/// <summary>Task responsible for receiving all packets from this host.</summary> private async Task ReceiveWorkerAsync() { while (!ReceiveCancel.IsCancellationRequested) { try { // Block if too many receive operations await ReceiveSemaphore.WaitAsync(); // Retrieve next available receive buffer from pool byte[] buffer = Allocator.CreatePacket(Config.ReceiveMTU); try { // Read next packet to the buffer EndPoint remote = new IPEndPoint( Socket.AddressFamily == AddressFamily.InterNetwork ? IPAddress.Any : IPAddress.IPv6Any, 0 ); TaskCompletionSource <int> tcs = new TaskCompletionSource <int>(); Socket.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref remote, result => { try { tcs.TrySetResult(Socket.EndReceiveFrom(result, ref remote)); } catch (Exception e) { tcs.TrySetException(e); } }, null); int length = await tcs.Task; // Increment statistics Statistics.SetSocketReceiveTicks(Ticks); Statistics.IncrementSocketReceiveCount(); Statistics.AddSocketReceiveBytes(length); // Start processing packet in a separate task // The task then releases semaphore and returns the buffer upon completion _ = Task.Factory.StartNew( () => Receive(remote as IPEndPoint, buffer, length), TaskCreationOptions.PreferFairness ); } catch { // Exception occured, release semaphore and return buffer here Allocator.ReturnPacket(ref buffer); ReceiveSemaphore.Release(); throw; } } catch (TaskCanceledException) when(ReceiveCancel.IsCancellationRequested) { // Receive worker has been stopped, ignore return; } catch (ObjectDisposedException) { // Host has been disposed, ignore return; } catch (Exception exception) { // Exception while receiving packet Listener.OnHostException(null, exception); } } }
/// <summary>Export all RSA parameters as a Base64 string.</summary> /// <returns>Base64 encoded parameters.</returns> public string ExportPrivateKey() { // Validate if (Disposed) { throw new ObjectDisposedException(GetType().FullName); } // Export parameters RSAParameters p = RSA.Value.ExportParameters(true); if (p.D.Length != 256) { throw new InvalidOperationException(string.Format( "D length {0} is not 256", p.D.Length )); } else if (p.DP.Length != 128) { throw new InvalidOperationException(string.Format( "DP length {0} is not 128", p.DP.Length )); } else if (p.DQ.Length != 128) { throw new InvalidOperationException(string.Format( "DQ length {0} is not 128", p.DQ.Length )); } else if (p.Exponent.Length != 3) { throw new InvalidOperationException(string.Format( "Exponent length {0} is not 3", p.Exponent.Length )); } else if (p.Exponent[0] != 1 || p.Exponent[1] != 0 || p.Exponent[2] != 1) { throw new InvalidOperationException(string.Format( "Exponent {0}, {1}, {2} is invalid", p.Exponent[0], p.Exponent[1], p.Exponent[2] )); } else if (p.InverseQ.Length != 128) { throw new InvalidOperationException(string.Format( "InverseQ length {0} is not 128", p.InverseQ.Length )); } else if (p.Modulus.Length != 256) { throw new InvalidOperationException(string.Format( "Modulus length {0} is not 256", p.Modulus.Length )); } else if (p.P.Length != 128) { throw new InvalidOperationException(string.Format( "P length {0} is not 128", p.P.Length )); } else if (p.Q.Length != 128) { throw new InvalidOperationException(string.Format( "Q length {0} is not 128", p.Q.Length )); } // Convert to Base64 byte[] key = Allocator.CreatePacket(1152); try { Array.Copy(p.D, 0, key, 0, 256); Array.Copy(p.DP, 0, key, 256, 128); Array.Copy(p.DQ, 0, key, 384, 128); Array.Copy(p.InverseQ, 0, key, 512, 128); Array.Copy(p.Modulus, 0, key, 640, 256); Array.Copy(p.P, 0, key, 896, 128); Array.Copy(p.Q, 0, key, 1024, 128); return(Convert.ToBase64String(key, 0, 1152)); } finally { Allocator.ReturnPacket(ref key); } }