예제 #1
0
        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;
                    }
                }
            });
        }
예제 #2
0
 public override void OnReceive(Context context, Intent intent)
 {
     BroadcastReceived?.Invoke(context, intent);
 }
예제 #3
0
        /// <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();
                }
            }
        }
예제 #4
0
        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);
        }