Пример #1
0
 public void Start()
 {
     NetworkClient.BeginReceive(NetworkMessageReceived, null);
     if (LocalNode != null)
     {
         Console.WriteLine("Network: Listening on " + NetworkClient.Client.LocalEndPoint);
     }
     RetryTimer.Change(10000, 10000);
 }
Пример #2
0
        private void Accept(IAsyncResult res)
        {
            var clientSocket = Server.EndAccept(res);

            clientSocket.ReceiveBufferSize = ClientBufferSize;
            var client = new NetworkClient(this, clientSocket, ClientBufferSize);

            OnConnect?.Invoke(client);
            client.BeginReceive();
            BeginAccept();
        }
Пример #3
0
        public BinaryClient(NetworkClient client)
        {
            _client = client;

            client.Connected += Client_Connected;
            client.Disconnected += Client_Disconnected;
            client.DataReceived += Client_DataReceived;

            if (_client.IsConnected)
            {
                _client.BeginReceive();
            }
        }
Пример #4
0
        private void NetworkMessageReceived(IAsyncResult result)
        {
            IPEndPoint endPoint = default(IPEndPoint);
            var        payload  = NetworkClient.EndReceive(result, ref endPoint);

            NetworkClient.BeginReceive(NetworkMessageReceived, null);
            var stream = new BinaryReader(new MemoryStream(payload), Encoding.UTF8);
            AsymmetricKeyParameter key;
            RemoteNode             node = null;

            if (endPoint.Address.Equals(IPAddress.Loopback))
            {
                key = CryptoProvider.PublicKey;
            }
            else
            {
                node = GetNode(endPoint);
                if (node == null)
                {
                    return;
                }
                key = node.PublicKey;
            }
            try
            {
                var id          = stream.ReadString();
                var flags       = (MessageFlags)stream.ReadByte();
                var transaction = stream.ReadUInt32();
                var timestamp   = new DateTime(stream.ReadInt64(), DateTimeKind.Utc);
                if (node != null)
                {
                    // TODO: Evaluate this margin of error, and this whole system in general that prevents resubmission
                    if (Math.Abs((timestamp - node.PreviousMessageTimestamp).TotalSeconds) > 10)
                    {
                        return;
                    }
                    node.PreviousMessageTimestamp = timestamp;
                }
                if (PacketFactories.ContainsKey(id))
                {
                    var packet = PacketFactories[id]();
                    packet.Transaction = transaction;
                    packet.Read(stream);
                    int signatureLength = (int)(stream.BaseStream.Length - stream.BaseStream.Position);
                    int messageLength   = (int)stream.BaseStream.Position;
                    stream.BaseStream.Seek(0, SeekOrigin.Begin);
                    byte[] message   = new byte[messageLength];
                    byte[] signature = new byte[signatureLength];
                    stream.BaseStream.Read(message, 0, message.Length);
                    stream.BaseStream.Read(signature, 0, signature.Length);
                    // Verify signature
                    if (!CryptoProvider.VerifySignature(message, signature, key))
                    {
                        Console.WriteLine("Warning: Received internode network packet with bad signature from {0}", endPoint);
                    }
                    else
                    {
                        if (id == typeof(ConfirmationPacket).Name)
                        {
                            HandleConfirmation(packet);
                        }
                        else if (PacketHandlers.ContainsKey(id))
                        {
                            PacketHandlers[id](packet, endPoint, this);
                        }
                        else
                        {
                            Console.WriteLine("Warning: Unhandled internode network packet with ID {0}", id);
                        }
                        if ((flags & MessageFlags.PropegateTransaction) > 0 && endPoint.Address == IPAddress.Loopback)
                        {
                            foreach (var target in Network)
                            {
                                if (target != node)
                                {
                                    Send(packet, target.EndPoint);
                                }
                            }
                        }
                        if ((flags & MessageFlags.ConfirmationRequired) > 0)
                        {
                            Send(new ConfirmationPacket(transaction), endPoint); // TODO: Don't re-handle duplicate transactions
                        }
                    }
                }
                else
                {
                    Console.WriteLine("Warning: Received unknown internode network packet ID {0}", id);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Warning: Error parsing internetwork message: {0}", e.GetType().Name);
            }
        }