Exemplo n.º 1
0
def invalid_connection(connection, peer):
    """
    Execute this if the peer has returned the NULL_RESPONSE flag.

    :param connection: name of the connection requested
    :param peer: ``net.Peer`` or tuple
    :return:
    """
    if isinstance(peer, tuple):
        host = peer[0]
        port = peer[1]
        connections = [
            str(connection)
            for connection in net.Peer().registered_connections.keys()
        ]
    else:
        host = peer.host
        port = peer.port
        connections = peer.registered_connections

    raise Exception("Peer does not have the connection you are requesting.\n\t"
                    "Peer: {0}@{1}\n\t"
                    "Registered Connections: \n\t\t{3}\n\t"
                    "Connection Requested: {2}".format(
                        host, port, connection, '\n\t\t'.join(connections)))
Exemplo n.º 2
0
def info(*args, **kwargs):
    """
    Return information about the peer requested.

    .. code-block:: python

        friendly_information = net.info(peer='somepeer')

    :return: peer.friendly_id
    """
    information = net.Peer()
    return {
        # friendly tag
        'tag': str(information),

        # host
        'host': information.host,
        'port': information.port,

        # user
        'user': getpass.getuser(),
        'executable': sys.executable,

        # app
        'group': information.group,
        'hub': information.hub,

        # interfaces
        'connections': sorted(list(information.registered_connections.keys())),
        'subscriptions':
        sorted(list(information.registered_subscriptions.keys())),
        'flags': sorted(list(information.registered_flags.keys())),
    }
Exemplo n.º 3
0
def null(*args, **kwargs):
    """
    Return a null response flag

    :return: NULL Flag
    """
    return net.Peer().get_flag("NULL")
Exemplo n.º 4
0
def connections(*args, **kwargs):
    """
    Return the connections registered with the peer.

    .. code-block:: python

        friendly_information = net.connections(peer='somepeer')

    :return: peer.CONNECTIONS
    """
    registered_connections = net.Peer().registered_connections

    return 'Connections on {1}:\n\t{0}'.format(
        '\n\n\t'.join([
            '{0}\n\t\t{1}'.format(key, registered_connections[key])
            for key in registered_connections.keys()
        ]),
        net.Peer().friendly_id)
Exemplo n.º 5
0
    def registry(func):
        @wraps(func)
        def handler(*args, **kwargs):
            return func(*args, **kwargs)

        # register the function with the peer handler
        net.Peer().register_flag(name, handler)

        return handler
Exemplo n.º 6
0
def subscription_handler(event, host, port, connection, *args, **kwargs):
    """
    Will register the incoming peer and connection with the local peers
    subscription of the event passed. This is for internal use only.

    :param event: event id
    :param host: foreign peer host
    :param port: foreign peer port
    :param connection: connection id
    """
    net.Peer().register_subscriber(event, host, port, connection)
Exemplo n.º 7
0
    def handle(self):
        """
        Handles all incoming requests to the server.
        """
        raw = self.request.recv(1024)

        local_peer = net.Peer()

        # response codes
        null = local_peer.get_flag('NULL').encode('ascii')
        invalid_connection = local_peer.get_flag('INVALID_CONNECTION').encode(
            'ascii')

        # if there is no data, bail and don't respond
        if not raw:
            self.request.sendall(null)
            return

        # convert from json
        try:
            data = raw.decode('ascii')

            try:
                data = json.loads(data)
            except Exception as err:
                net.LOGGER.info(
                    "Could not decode server request data: {0}".format(err))

            # skip if there is no data in the request
            if not data:
                self.request.sendall(null)
                return

            # Get the registered connection
            connection = local_peer.registered_connections.get(
                data['connection'])

            # throw invalid if the connection doesn't exist on this peer.
            if not connection:
                self.request.sendall(invalid_connection)
                return

            # execute the connection handler and send back
            response = connection(*data['args'], **data['kwargs'])

            self.request.sendall(json.dumps(response).encode('ascii'))

        except Exception as err:
            net.LOGGER.error(err)
            net.LOGGER.error(traceback.format_exc())

            packet = {'payload': 'error', 'traceback': traceback.format_exc()}

            self.request.sendall(json.dumps(packet).encode('ascii'))
Exemplo n.º 8
0
def peer_group(name=None, hubs_only=False, on_host=False):
    """
    Get a list of peers that are have been detected by net. You can get all
    peers in the same group as the requesting peer just by calling this function
    with no filter name. You can also request to only get the hubs for a
    specific group.

    .. code-block:: python

        # Will get all peers in the same group that net.Peer() is in.
        peers = net.peer_group()

        # Peers in group1
        peers = net.peer_group("group1")

        # Get the hubs only for the group net.Peer() is in.
        hubs = net.peer_group(hubs_only=True)

        # Get only the hubs in group1
        hubs = net.peer_group("group1", hubs_only=True)

    :param name: name of the group
    :param hubs_only: bool
    :param on_host: bool
    :return: list of ``net.Peer``
    """
    group_peers = []
    if not name:
        name = net.Peer().group

    found_peers = peers(groups=[name], hubs_only=hubs_only, on_host=on_host)

    group_data = found_peers.get(name)
    if group_data:
        return group_data
    return group_peers
Exemplo n.º 9
0
        def interface(*args, **kwargs):

            new_args, new_kwargs = func(*args, **kwargs)
            net.Peer().trigger_event(name, *new_args, **new_kwargs)

            return new_args, new_kwargs
Exemplo n.º 10
0
def get_peers(groups, on_host, hubs_only):
    """
    Get a list of all valid remote peers.

    :param groups: List of groups
    :param on_host: Search only localhost
    :param hubs_only: Get Hubs only
    :return: List of peer addresses
    """
    global PEERS
    PEERS = {
        'peers': {}
    }

    # get this peer for pinging
    peer = net.Peer()
    server = peer.server

    # create subnet
    network = [net.HOST_IP]
    if not on_host:
        network = local_network()

    # logging help
    total_hosts = len(network)
    total_ports = len(server.ports())
    net.LOGGER.debug(
        "Calculated network sweep: {0} hosts X {1} ports = {2} pings".format(
            total_hosts, total_ports, total_hosts * total_ports
        )
    )

    # skip the threading integration if the environment does not call for it.
    if net.THREAD_LIMIT <= 0:
        return find_peers_in_block(network, groups, hubs_only)

    # calculate thread chunk. There should always be at least one thread chunk
    thread_chunks = max(int(math.ceil(total_hosts/net.THREAD_LIMIT)), 1)

    # loop over and spawn threads
    start = 0
    threads = []

    for chunk in range(0, net.THREAD_LIMIT):
        end = start + thread_chunks

        thread = threading.Thread(
            target=find_peers_in_block,
            args=(network[start:end], groups, hubs_only)
        )
        thread.setName("Network_Scanner_" + str(chunk))
        thread.daemon = True
        threads.append(thread)
        thread.start()

        start = end

    # wait for all worker threads to finish
    for thread in threads:
        thread.join()

    return PEERS
Exemplo n.º 11
0
def find_peers_in_block(ips, groups=None, hubs_only=False):
    """
    Sniffs out peers in the defined group based on the list of ip's

    :param ips: list of ip addresses
    :param groups: the list of groups you'd like to filter with. Defaults to the
     same as the current peer.
    :return: List of peer addresses
    """
    global PEERS

    # pull in the local peer
    peer = net.Peer()
    server = peer.server

    if not groups:
        groups = [peer.group]

    # loop over all the addresses
    for address in ips:

        # loop over ports
        for port in server.ports():

            # skip self
            if port == server.port and address == server.host:
                continue

            try:
                # ping the peer and if it responds with the proper info,
                # register it. Shut off the logger for this so we dont spam
                # the console.
                net.LOGGER.disabled = True
                info = net.info(peer=(address, port), time_out=0.1)
                net.LOGGER.disabled = False

                # skip registering this if the info is already in the
                # registry.
                if info['tag'] in PEERS['peers'].values():
                    continue

                # filter out peers that aren't in the groups requested.
                if info['group'] not in groups:
                    continue

                # filter out non-hubs if that is what was requested
                if hubs_only and not info['hub']:
                    continue

                # construct the peer representation
                new_peer = net.Peer(
                    host=info['host'],
                    port=info['port'],
                    group=info['group'],
                    hub=info['hub'],
                    subscriptions=info['subscriptions'],
                    connections=info['connections'],
                    flags=info['flags'],
                )

                # acquire the lock and register
                LOCK.acquire()

                # register with the general information per peer
                PEERS['peers'][info['tag']] = new_peer

                # register with the group registry
                group_registry = PEERS.setdefault(info['group'], [])
                group_registry.append(new_peer)

                # release the shared resource
                LOCK.release()

            except (PermissionError, ConnectionRefusedError, OSError) as err:
                net.LOGGER.disabled = False
Exemplo n.º 12
0
def subscribe(event, groups=None, hubs_only=False, peers=None, on_host=None):
    """
    Subscribe to an event on another peer or set of peers. When the peer
    triggers an event using ``net.event``, the peer will take the arguments
    passed and forward them to this function. By default, this will subscribe to
    all peers. You can also manually filter the peers by selectively passing in
    only the peers you want to subscribe to using the ``peers`` keyword argument.

    Subscribe to "some_event" on group1 peers only.

    .. code-block:: python

        group1_peers = net.peers(groups=['group1'])

        @net.subscribe("some_event", group1_peers)
        def your_function(subscription_args, subscription_kwarg=None):
            return some_value

    Subscribe to "some_event" on a single peer.

    .. code-block:: python

        peer = net.peers()[0]

        @net.subscribe("some_event", peer)
        def your_function(subscription_args, subscription_kwarg=None):
            return some_value

    Subscribe to "some_event" on all peers.

    .. code-block:: python

        @net.subscribe("some_event")
        def your_function(subscription_args, subscription_kwarg=None):
            return some_value

    """
    this_peer = net.Peer()

    # handle peers arg
    if not peers:
        peers = net.peers(
            hubs_only=hubs_only,
            groups=groups,
            on_host=on_host
        )['peers'].values()
    else:
        if not isinstance(peers, (list, tuple)):
            peers = [peers]

    def wrapper(func):

        # build the connection id
        connection = this_peer.register_connection(func)

        # loop over all the requested peers
        for peer in peers:
            peer.subscription_handler(event, this_peer.host, this_peer.port, connection)

        return func
    return wrapper