Пример #1
0
        print("EXITING CLEANLY" if intentional else "EXITING BADLY")
        raise SystemExit(int(not intentional))


class ChatProgram(BaseProgram):
    def recv(self, packet, interface):
        print('\n>> {}'.format(packet.decode()))


if __name__ == "__main__":
    links = [
        UDPLink('en0', 2010),
        UDPLink('en1', 2011),
        UDPLink('en2', 2012),
        UDPLink('en3', 2013)
    ]
    node = Node(links, 'me', Filters=(UniqueFilter, ), Program=ChatProgram)
    [link.start() for link in links]
    node.start()

    try:
        while True:
            print("------------------------------")
            message = input('<< ')
            node.send(bytes(message, 'UTF-8'))
            time.sleep(0.3)

    except (EOFError, KeyboardInterrupt):  # graceful CTRL-D & CTRL-C
        node.stop()
        [link.stop() for link in links]
Пример #2
0
    config = bedroom_config

    links = [UDPLink('en0', 2010)]

    node = Node(links, config['node_name'], Filters=[], Program=Albus)

    node.program.apply_config(config)

    [link.start() for link in links]
    node.start()

    print(
        "Run lan-chat.py on another laptop to talk between the two of you on en0."
    )
    try:
        while True:
            message = input('<< ')

            message_dict = create_message_dict('Light On', '',
                                               config['node_name'], 'light')
            message_bytes = dict_to_bytes(message_dict)

            node.send(message_bytes)

            time.sleep(0.3)

    except (EOFError, KeyboardInterrupt):
        node.stop()
        [link.stop() for link in links]
Пример #3
0
from mesh.links import UDPLink
from mesh.programs import BaseProgram
from mesh.filters import UniqueFilter
from mesh.node import Node



class ChatProgram(BaseProgram):
    def recv(self, packet, interface):
        print('\n>> {}'.format(packet.decode()))


if __name__ == "__main__":
    links = [UDPLink('en0', 2010), UDPLink('en1', 2011), UDPLink('en2', 2012), UDPLink('en3', 2013)]
    node = Node(links, 'me', Filters=(UniqueFilter,), Program=ChatProgram)
    [link.start() for link in links]
    node.start()

    print("Run lan-chat.py on another laptop to talk between the two of you on en0.")
    try:
        while True:
            print("------------------------------")
            message = input('<< ')
            node.send(bytes(message, 'UTF-8'))
            time.sleep(0.3)

    except (EOFError, KeyboardInterrupt):   # graceful CTRL-D & CTRL-C
        node.stop()
        [link.stop() for link in links]
Пример #4
0
class Node(threading.Thread):
    def __init__(self, name, port=5000, blockchain=Blockchain()):
        threading.Thread.__init__(self)

        self.name = name
        self.address = ni.ifaddresses('en0')[ni.AF_INET][0]['addr']

        self.blockchain = blockchain

        self.peer_info = {}
        self.peers = set()

        self.links = [UDPLink('en0', port=port)]
        self.network = NetworkComponent(self.links,
                                        name,
                                        Filters=(DuplicateFilter, ))

        self.keep_listening = True
        self.ready = False
        self.synced = False

        self.heartbeat_thread = threading.Thread(target=self.send_heartbeat)

        # Start Network Component
        [link.start() for link in self.links]
        self.network.start()
        self.heartbeat_thread.start()
        self.start()

    @property
    def identifier(self):
        parsed_url = urlparse(self.address)
        return f'{parsed_url.path}:{self.name}'

    # Threading
    def run(self):
        while self.keep_listening:
            # Remove peers who have disconnected after 30 mins
            disconnected_peers = []
            for peer_id, info in self.peer_info.items():
                if info['lastsend'] - info['lastrecv'] > 60 * 30:
                    disconnected_peers.append(peer_id)

            for peer_id in disconnected_peers:
                print(f'Disconnecting {peer_id} for being idle for 30 minutes')
                self.peer_info.pop(peer_id)
                self.peers.remove(peer_id)

            # Check for new packets
            for interface in self.network.interfaces:
                try:
                    self.recv(self.network.inq[interface].get(timeout=0),
                              interface)
                except Empty:
                    sleep(0.1)

    def stop(self):
        self.keep_listening = False

        self.network.stop()
        [link.stop() for link in self.links]

        self.heartbeat_thread.join()
        self.join()

    # I/O
    def send(self, type, message='', target='', encoding='UTF-8'):
        data = json.dumps({
            'type': type,
            'identifier': self.identifier,
            'message': message,
            'target': target
        })

        print('\nsending {}'.format(data))

        self.network.send(bytes(data, encoding))

        # Update Peer Info
        if target:
            self.peer_info[target]['lastsend'] = time()
        else:
            for peer in self.peers:
                self.peer_info[peer]['lastsend'] = time()

    def recv(self, packet, interface):
        data = json.loads(packet.decode())

        # Filter Packets not targeted to you
        if len(data['target']) != 0 and data['target'] != self.identifier:
            return

        print('\nreceived {}'.format(data))

        self.handle_data(data)

        # Update Peer Info
        sender = data['identifier']
        if sender in self.peers:
            self.peer_info[sender]['lastrecv'] = time()

    def handle_data(self, data):
        # Handle Request
        msg_type = data['type']
        sender = data['identifier']
        message = json.loads(data['message']) if data['message'] else {}

        if msg_type == 'version':
            registered = self.register_peer(sender,
                                            height=message.get('height'))

            if registered:
                self.send('verack', target=sender)
                self.send('version',
                          target=sender,
                          message=json.dumps(
                              {'height': len(self.blockchain.chain)}))
            print(self.peers)

        elif msg_type == 'verack':
            self.ready = True

        if self.ready:
            if msg_type == 'heartbeat':
                self.send('heartbeatack', target=sender)

            elif msg_type == 'heartbeatack':
                pass

    def send_heartbeat(self):
        while self.keep_listening and self.ready:
            sleep(60 * 30)
            self.send('heartbeat')

    # Methods
    def register_peer(self, identifier, height):
        """
        Add a new node to the list of nodes

        @param identifier: <str> Identifier of the node (eg: 'address:name')

        @return: <bool> True if a new peer was registered, False otherwise
        """

        if identifier not in self.peers:
            self.peers.add(identifier)
            self.peer_info[identifier] = {
                'identifier': identifier,
                'lastrecv': time(),
                'lastsend': 0,
                'height': height
            }

            return True
        else:
            return False

    def get_peer(self, index=None):
        """
        Returns a random peer identifier unless specified by the parameter

        @param index: <int> Index of the peer in the peer list

        @return: <str> Peer identifier
        """

        if index is None:
            index = randint(0, len(self.peers) - 1)

        i = 0
        for p in self.peers:
            if i == index:
                return p
            i += 1