public async void Run() { IsRunning = true; await Task.Run(async() => { while (IsRunning) { try { string response = await conn.WaitForResponse(); Tuple <string[], PacketType> packet = packetHandler.HandlePacket(response); switch (packet.Item2) { case PacketType.Status: StatusReceived?.Invoke(new StatusArgs(packet.Item1[1])); break; case PacketType.SyncData: SyncDataReceived?.Invoke(new SyncDataArgs(packet.Item1)); break; case PacketType.Heart: HeartReceived?.Invoke(new HeartArgs(packet.Item1[1])); break; case PacketType.ClientDisconnect: ClientDisconnectReceived?.Invoke(new EventArgs()); break; case PacketType.Broadcast: BroadcastReceived?.Invoke(new BroadcastArgs(packet.Item1[1])); break; case PacketType.Message: MessageReceived?.Invoke(new MessageArgs(packet.Item1[1])); break; } } catch (Exception e) { IsRunning = false; } } }); }
public override void OnReceive(Context context, Intent intent) { BroadcastReceived?.Invoke(context, intent); }
/// <summary> /// /// </summary> public async Task ReceiveBroadcast(CancellationToken token) { UdpClient client = null; Task t = null; try { client = new UdpClient(10080); var t1 = Task.Run(() => { while (true) { var remoteEndPoint = default(IPEndPoint); var bytes = client.Receive(ref remoteEndPoint); if (bytes.Length == 2 && bytes[0] == 0xcc && bytes[1] == 0xdd) { BroadcastReceived?.Invoke(remoteEndPoint.Address.ToString()); } } }); var t2 = Task.Run(() => { var count = 0; while (true) { if (count > 30) { break; } count++; if (token.IsCancellationRequested) { client.Close(); return; } Thread.Sleep(500); } client.Close(); }); t = Task.WhenAll(t1, t2); await t; } catch { if (t != null) { throw t.Exception; } throw; } finally { if (client != null) { client.Close(); } } }
private async Task SynchronizeRemoteToLocalAsync() { DebugPrint("Enter Remote to Local"); var have = await ChannelsExtensions.ReadAsync(haveChannel).ConfigureAwait(false); DebugPrint("Have is {0}", have.MerkleRootHash); var isRemoteRootSyncedLocally = await IsRemoteObjectHeldLocally(have.MerkleRootHash).ConfigureAwait(false); DebugPrint("IRRSL {0}", isRemoteRootSyncedLocally); if (!isRemoteRootSyncedLocally) { var nodesToImport = new List <Tuple <string, MerkleNode> >(); var neededHashes = new LinkedList <string>(); neededHashes.AddLast(have.MerkleRootHash); while (neededHashes.Count != 0) { var hashesReadLocally = new HashSet <string>(); foreach (var hash in neededHashes) { var localNode = await localMerkleTree.GetNodeAsync(hash).ConfigureAwait(false); if (localNode != null) { nodesToImport.Add(Tuple.Create(hash, localNode)); hashesReadLocally.Add(hash); continue; } var need = new NeedPacket { MerkleRootHash = hash }; DebugPrint("SEND NEED {0}", need.MerkleRootHash); neighbor.SendAsync(serializer.ToByteArray(need)).Forget(); } Console.WriteLine($"Found {neededHashes.Count} messages to sync"); foreach (var i in Enumerable.Range(0, neededHashes.Count)) { var hash = neededHashes.First(); neededHashes.RemoveFirst(); if (hashesReadLocally.Contains(hash)) { continue; } var give = await ChannelsExtensions.ReadAsync(giveChannel).ConfigureAwait(false); Console.WriteLine($"Got hash {give.NodeHash}"); nodesToImport.Add(Tuple.Create(give.NodeHash, give.Node)); if (!await IsRemoteObjectHeldLocally(give.Node.LeftHash).ConfigureAwait(false)) { neededHashes.AddLast(give.Node.LeftHash); } if (!await IsRemoteObjectHeldLocally(give.Node.RightHash).ConfigureAwait(false)) { neededHashes.AddLast(give.Node.RightHash); } } } var broadcastMessagesByNodeHash = nodesToImport.Where(n => n.Item2.TypeTag == MerkleNodeTypeTag.Data) .ToDictionary( n => n.Item1, n => broadcastMessageSerializer.Deserialize(n.Item2.Contents) ); Console.WriteLine($"Need to add {broadcastMessagesByNodeHash.Count} hashes that we don't have"); var neededSourceIdHashes = broadcastMessagesByNodeHash.Select(kvp => kvp.Value.SourceIdHash) .GroupBy(sourceIdHash => sourceIdHash.ToHexString()) .Select(g => new { Bytes = g.First(), Hex = g.Key }) .Where(pair => !IdentityManager.IsKnownIdentity(pair.Bytes)) .ToList(); foreach (var neededSourceId in neededSourceIdHashes) { var whois = new WhoisPacket { IdHash = neededSourceId.Bytes }; DebugPrint("SEND WHOIS {0}", neededSourceId.Hex); neighbor.SendAsync(serializer.ToByteArray(whois)).Forget(); } foreach (var i in Enumerable.Range(0, neededSourceIdHashes.Count)) { var ident = await ChannelsExtensions.ReadAsync(identChannel).ConfigureAwait(false); Identity.ValidateAndAdd(ident.TrustChain); } foreach (var neededSourceId in neededSourceIdHashes) { if (!IdentityManager.IsKnownIdentity(neededSourceId.Bytes)) { throw new InvalidStateException(); } } foreach (var tuple in nodesToImport) { var node = tuple.Item2; if (node.Descendents == 0 && await localMerkleTree.GetNodeAsync(tuple.Item1).ConfigureAwait(false) == null) { var isDataNode = node.TypeTag == MerkleNodeTypeTag.Data; BroadcastMessageDto message = isDataNode ? broadcastMessageSerializer.Deserialize(node.Contents) : null; var sender = IdentityManager.LookupIdentity(message.SourceIdHash); if (message.DestinationIdHash.All(val => val == 0)) { if ((sender.HeldPermissions & Permission.Broadcast) == 0) { Console.WriteLine("Sender does not have broadcast permissions. Malicious peer!"); throw new InvalidStateException(); } } else { if ((sender.HeldPermissions & Permission.Unicast) == 0) { Console.WriteLine("Sender does not have unicast permissions. Malicious peer!"); throw new InvalidStateException(); } } } } await remoteMerkleTree.ImportAsync(have.MerkleRootHash, nodesToImport).ConfigureAwait(false); Console.WriteLine($"Currently have {nodesToImport.Count} nodes to import still"); foreach (var tuple in nodesToImport) { var node = tuple.Item2; if (node.Descendents == 0 && await localMerkleTree.GetNodeAsync(tuple.Item1).ConfigureAwait(false) == null) { var isDataNode = node.TypeTag == MerkleNodeTypeTag.Data; BroadcastMessageDto message = isDataNode ? broadcastMessageSerializer.Deserialize(node.Contents) : null; Console.WriteLine("Got data node"); var insertionResult = await localMerkleTree.TryInsertAsync(tuple.Item2).ConfigureAwait(false); if (insertionResult.Item1 && isDataNode) { byte[] decryptedPayload; Console.WriteLine("Got a message"); if (identity.TryDecodePayload(message, out decryptedPayload)) { BroadcastReceived?.Invoke(new MessageReceivedEventArgs(neighbor, new BroadcastMessage { SourceId = IdentityHash.GetFlyweight(message.SourceIdHash), DestinationId = IdentityHash.GetFlyweight(message.DestinationIdHash), DecryptedPayload = decryptedPayload, Dto = message })); } } } } } DebugPrint("SEND DONE"); await neighbor.SendAsync(serializer.ToByteArray(new DonePacket())).ConfigureAwait(false); }