Example #1
0
        /// <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);
                }
            }
        }
Example #2
0
        /// <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);
            }
        }