示例#1
0
        /// <summary>
        /// Handle incoming packets related to connection setup
        /// </summary>
        /// <param name="message">The message to handle</param>
        /// <returns>A PacketResponse indicating if the message was consumed</returns>
        public PacketResponse HandlePacket(Message message)
        {
            switch (message.MessageType)
            {
            case MessageType.HeartbeatRequest:
                var msg = new Message(MessageType.Heartbeat, message.Sender)
                {
                    DataAsString = Dns.GetHostName()
                };
                Outbox.SendUnencryptedMessage(msg);
                if (!ConnectedPeers.ContainsKey(message.Sender))
                {
                    ConnectedPeers.Add(message.Sender, message.DataAsString);
                }
                return(PacketResponse.Accept);

            case MessageType.Heartbeat:
                if (!ConnectedPeers.ContainsKey(message.Sender))
                {
                    ConnectedPeers.Add(message.Sender, message.DataAsString);
                }
                return(PacketResponse.Accept);

            case MessageType.EncryptionPacket:
                SecurityManager.GetInstance().SetKeysFromPacket(message.Data);
                Inbox.GetInstance().UseEncryption = true;
                ConnectionDone = true;

                return(PacketResponse.AcceptAndFinish);

            default:
                return(PacketResponse.Decline);
            }
        }
示例#2
0
        /// <summary>
        /// Handles a PingRequest packet by creating a <see cref="PongListener">PongListener</see> and sending a ping to the suspect
        /// </summary>
        /// <param name="pingRequest">The received PingRequest object</param>
        /// <returns>Accept or Decline depending on what type of packet was received</returns>
        public PacketResponse HandlePacket(Message pingRequest)
        {
            if (pingRequest.MessageType != MessageType.PingRequest)
            {
                return(PacketResponse.Decline);
            }

            IPAddress peerToPing;
            var       valid = IPAddress.TryParse(pingRequest.DataAsString, out peerToPing);

            if (!valid)
            {
                pingRequest.DeemInvalid();
                return(PacketResponse.Decline);
            }

            var pongListener = new PongListener(pingRequest.Sender, peerToPing);

            networkListener.RegisterHandler(pongListener, PongListener.Timeout);

            var ping = new Message(MessageType.Ping, peerToPing);

            Outbox.SendMessage(ping);

            return(PacketResponse.Accept);
        }
示例#3
0
        /// <summary>
        /// Recieves a voting number and reports to it's own database
        /// that the person with that specific voting number has voted.
        /// </summary>
        /// <param name="message">The Message-object containing the voting number
        /// of the person who has been given a voting card</param>
        /// <returns></returns>
        /// Author: Michael Oliver Urhøj Mortensen
        public PacketResponse HandlePacket(Message message)
        {
            if (message.MessageType != MessageType.Vote)
            {
                return(PacketResponse.Decline);
            }

            try
            {
                var voterNumber = Convert.ToUInt64(message.DataAsString);
                if (!localVoteListener.Peers.ContainsKey(message.Sender)) //Error in sender - kill'im
                {
                    var response = new Message(MessageType.PeerDead, message.Sender)
                    {
                        DataAsString = message.Sender.ToString()
                    };
                    Outbox.SendMessage(response);
                }
                else
                {
                    var response = new Message(MessageType.VoteOk, message.Sender)
                    {
                        Data = message.Data
                    };
                    Outbox.SendMessage(response);
                    Database.GetInstance.SetVoted(voterNumber, true);
                }
            }
            catch (Exception)
            {
                message.DeemInvalid();
                return(PacketResponse.Decline);
            }
            return(PacketResponse.Accept);
        }
示例#4
0
        /// <summary>
        /// The pong listener times out when it doesn't receive a pong. This will be reported to the initiator
        /// </summary>
        public void TimedOut()
        {
            Message pingFailed = new Message(MessageType.PingFailed, initiator)
            {
                DataAsString = suspect.ToString()
            };

            Outbox.SendMessage(pingFailed);
        }
示例#5
0
        /// <summary>
        /// Broadcasts a heartbeat to the entire network
        /// </summary>
        public void BroadcastHeartbeatRequest()
        {
            var msg = new Message(MessageType.HeartbeatRequest)
            {
                DataAsString = Dns.GetHostName()
            };

            Outbox.SendUnencryptedMessage(msg);
        }
示例#6
0
        /// <summary>
        /// Handle an incomping Pong packet
        /// </summary>
        /// <param name="message">The ping message to process</param>
        /// <returns>Accept if it's a ping message, Decline otherwise</returns>
        public PacketResponse HandlePacket(Message message)
        {
            if (message.MessageType != MessageType.Pong || !message.Sender.Equals(suspect))
            {
                return(PacketResponse.Decline);
            }

            var pingOK = new Message(MessageType.PingOk, initiator)
            {
                DataAsString = suspect.ToString()
            };

            Outbox.SendMessage(pingOK);

            return(PacketResponse.AcceptAndFinish);
        }
示例#7
0
        /// <summary>
        /// Send the generated key and IV directly to the discovered peers
        /// </summary>
        public void SendKey()
        {
            if (ConnectedPeers.Count < Program.MinimumPeerCount)
            {
                throw new NotEnoughPeersException(ConnectedPeers.Count);
            }

            foreach (var ipaddress in ConnectedPeers)
            {
                var keymsg = new Message(MessageType.EncryptionPacket, ipaddress.Key);
                keymsg.Data = SecurityManager.GetInstance().GetKeysAsPacket();
                Outbox.SendUnencryptedMessage(keymsg);
            }
            Inbox.GetInstance().UseEncryption = true;
            ConnectionDone = true;
        }
示例#8
0
        /// <summary>
        /// Creates a new PingRequestResponseListener and sends out a new PingRequest
        /// message to each of the peers that has not yet replied in the VoteReplyList.
        /// </summary>
        public void TimedOut()
        {
            var prrl = new PingRequestResponseListener(networkListener, vote);

            networkListener.RegisterHandler(prrl, PingRequestResponseListener.Timeout);

            foreach (var peer in vote.VoteReplyList)
            {
                if (!peer.Value)
                {
                    var pingRequest = new Message(MessageType.PingRequest)
                    {
                        DataAsString = peer.Key.ToString()
                    };
                    Outbox.SendMessage(pingRequest);
                }
            }
        }
示例#9
0
        /// <summary>
        /// Handles the Message:
        /// If the MessageType is of any other type than "VoteOK" it ignores the Message.
        /// If it is of the type "VoteOK" the following scenarios may happen:
        /// -   If the sender is not in the VoteReplyList, then that sender is considered dead
        ///     and a reply is send out to the sender to notify it about this. The sender dies.
        /// -   Notifies the vote object that a peer has replied "VoteOK".
        /// </summary>
        /// <param name="message">The Message that is broadcasted.</param>
        /// <returns>
        /// PacketResponse.AcceptAndFinish if all the peers have replied "VoteOK",
        /// PacketResponse.Accept if not.
        /// </returns>
        public PacketResponse HandlePacket(Message message)
        {
            if (message.MessageType != MessageType.VoteOk)
            {
                return(PacketResponse.Decline);
            }

            if (!vote.VoteReplyList.ContainsKey(message.Sender)) //Error in sender - kill'im
            {
                var response = new Message(MessageType.PeerDead, message.Sender)
                {
                    DataAsString = message.Sender.ToString()
                };
                Outbox.SendMessage(response);
            }
            else
            {
                vote.Replied(message.Sender);
            }
            return(vote.IsAcknowledged() ? PacketResponse.AcceptAndFinish : PacketResponse.Accept);
        }
示例#10
0
        /// <summary>
        /// The PRRL timed out.
        /// All peers that did not respond are registered as non-responding, and a new PRRL is created from the peer list
        /// </summary>
        public void TimedOut()
        {
            foreach (var nonRespondingPeer in nonRespondingPeers)
            {
                vote.SetPeerState(nonRespondingPeer.Key, PeerState.MaybeDead);
            }
            if (retries + 1 >= networkStabilityTreshold)
            {
                throw new NotEnoughPeersException(0);
            }

            var prrl = new PingRequestResponseListener(networkListener, vote, retries + 1);

            networkListener.RegisterHandler(prrl, Timeout);

            foreach (var peer in nonRespondingPeers)
            {
                var pingRequest = new Message(MessageType.PingRequest)
                {
                    DataAsString = peer.Key.ToString()
                };
                Outbox.SendMessage(pingRequest);
            }
        }
示例#11
0
        /// <summary>
        /// Update the list of responses from an incoming packet
        /// </summary>
        /// <param name="nonRespondingPeer">The unresponsive peer that has new data</param>
        /// <param name="sender">The sender of the new data</param>
        /// <param name="type">The message type that was received</param>
        private void UpdateResponses(IPAddress nonRespondingPeer, IPAddress sender, MessageType type)
        {
            if (type == MessageType.PingOk)
            {
                nonRespondingPeers.Remove(nonRespondingPeer);
                vote.SetPeerState(nonRespondingPeer, PeerState.Alive);
            }
            else
            {
                nonRespondingPeers[nonRespondingPeer][sender] = PingRequestResponse.No;

                //If all living peers answered No, broadcast that the peer must be dead.
                if (nonRespondingPeers[nonRespondingPeer].All(responder => responder.Value == PingRequestResponse.No))
                {
                    nonRespondingPeers.Remove(nonRespondingPeer);
                    vote.SetPeerState(nonRespondingPeer, PeerState.Dead);
                    var msg = new Message(MessageType.PeerDead)
                    {
                        DataAsString = nonRespondingPeer.ToString()
                    };
                    Outbox.SendMessage(msg);
                }
            }
        }