public void Start() { NetworkClient.BeginReceive(NetworkMessageReceived, null); if (LocalNode != null) { Console.WriteLine("Network: Listening on " + NetworkClient.Client.LocalEndPoint); } RetryTimer.Change(10000, 10000); }
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(); }
public BinaryClient(NetworkClient client) { _client = client; client.Connected += Client_Connected; client.Disconnected += Client_Disconnected; client.DataReceived += Client_DataReceived; if (_client.IsConnected) { _client.BeginReceive(); } }
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); } }