Example #1
0
    def _timertransmit(self, now):
        """A periodic handler that iterates through the nodes and sends
        any packets that are queued for delivery.

        Args:
            now (float): Current time.
        """
        srcnode = self.LocalNode

        dstnodes = self.peer_list(True)
        while len(dstnodes) > 0:
            newnodes = []
            for dstnode in dstnodes:
                msg = dstnode.get_next_message(now)
                if msg:
                    if dstnode.Enabled or msg.IsSystemMessage:
                        # basically we are looping through the nodes & as long
                        # as there are messages pending then come back around &
                        # try again
                        newnodes.append(dstnode)

                        packet = message.Packet()
                        packet.add_message(msg, srcnode, dstnode,
                                           self.next_sequence_number())
                        packet.TransmitTime = now

                        if packet.IsReliable:
                            self.PendingAckMap[packet.SequenceNumber] = packet

                        self._dowrite(packet.pack(), dstnode)

            dstnodes = newnodes
Example #2
0
    def datagramReceived(self, data, address):
        """Handles a received datagram.

        Find a handler for the message if one exists, and call it if
        the message has not already been handled. Also forward to peers
        as appropriate.

        Args:
            data (str): the text of the message
            address (str): host:port network address of the peer
        """

        if not self.ProcessIncomingMessages:
            return

        self.PacketStats.BytesReceived.add_value(len(data))

        # unpack the header
        try:
            packet = message.Packet()
            packet.unpack(data)
        except:
            logger.exception('failed to unpack message')
            return

        # Grab peer information if it is available, unless this is a system
        # message we don't process any further without a known peer
        srcpeer = self.NodeMap.get(packet.SenderID)
        if srcpeer:
            srcpeer.reset_ticks()

        # Handle incoming acknowledgements first, there is no data associated
        # with an ack
        if packet.IsAcknowledgement:
            if srcpeer:
                self._handleack(packet)
            return

        # first thing to do with the message is to send an ACK, all
        # retransmissions will be handled by the sending node, if the
        # IsReliable flag is set then this is not a system message & we know
        # that the peer exists
        if packet.IsReliable:
            if srcpeer:
                self._sendack(packet, srcpeer)

        # now unpack the rest of the message
        try:
            minfo = message.unpack_message_data(packet.Data)
        except:
            logger.exception('unable to decode message with length %d',
                             len(data))
            return

        # if we don't have a handler, thats ok we just dont do anything
        # with the message, note the missing handler in the logs however
        typename = minfo['__TYPE__']
        self.MessageStats.MessageType.increment(typename)

        if typename not in self.MessageHandlerMap:
            logger.info('no handler found for message type %s from %s',
                        minfo['__TYPE__'], srcpeer or packet.SenderID[:8])
            return

        try:
            msg = self.unpack_message(typename, minfo)
            msg.TimeToLive = packet.TimeToLive - 1
            msg.SenderID = packet.SenderID
        except:
            logger.exception(
                'unable to deserialize message of type %s from %s', typename,
                packet.SenderID[:8])
            return

        # if we have seen this message before then just ignore it
        if msg.Identifier in self.MessageHandledMap:
            logger.debug('duplicate message %s received from %s', msg,
                         packet.SenderID[:8])
            self.PacketStats.DuplicatePackets.increment()

            # if we have received a particular message from a node then we dont
            # need to send another copy back to the node, just remove it from
            # the queue
            try:
                if srcpeer:
                    srcpeer.dequeue_message(msg)
            except:
                pass

            return

        # verify the signature, this is a no-op for the gossiper, but
        # subclasses might override the function, system messages need not have
        # verified signatures
        if not msg.IsSystemMessage and not msg.verify_signature():
            logger.warn('unable to verify message %s received from %s',
                        msg.Identifier[:8], msg.OriginatorID[:8])
            return

        # Handle system messages,these do not require the existence of
        # a peer. If the packet is marked as a system message but the message
        # type does not, then something bad is happening.
        self.PacketStats.MessagesHandled.increment()

        if srcpeer or msg.IsSystemMessage:
            self.handle_message(msg)
            return

        logger.warn('received message %s from an unknown peer %s', msg,
                    packet.SenderID[:8])