Exemple #1
0
    async def connect(cls, remote: NodeAPI, private_key: datatypes.PrivateKey,
                      token: CancelToken) -> TransportAPI:
        """Perform the auth and P2P handshakes with the given remote.

        Return an instance of the given peer_class (must be a subclass of
        BasePeer) connected to that remote in case both handshakes are
        successful and at least one of the sub-protocols supported by
        peer_class is also supported by the remote.

        Raises UnreachablePeer if we cannot connect to the peer or
        HandshakeFailure if the remote disconnects before completing the
        handshake or if none of the sub-protocols supported by us is also
        supported by the remote.
        """
        try:
            (aes_secret, mac_secret, egress_mac, ingress_mac, reader,
             writer) = await auth.handshake(remote, private_key, token)
        except (ConnectionRefusedError, OSError) as e:
            raise UnreachablePeer(f"Can't reach {remote!r}") from e

        return cls(
            remote=remote,
            private_key=private_key,
            reader=reader,
            writer=writer,
            aes_secret=aes_secret,
            mac_secret=mac_secret,
            egress_mac=egress_mac,
            ingress_mac=ingress_mac,
        )
Exemple #2
0
async def handshake(remote: Node,
                    privkey: datatypes.PrivateKey,
                    peer_class: 'Type[BasePeer]',
                    headerdb: 'BaseAsyncHeaderDB',
                    network_id: int,
                    token: CancelToken,
                    ) -> 'BasePeer':
    """Perform the auth and P2P handshakes with the given remote.

    Return an instance of the given peer_class (must be a subclass of BasePeer) connected to that
    remote in case both handshakes are successful and at least one of the sub-protocols supported
    by peer_class is also supported by the remote.

    Raises UnreachablePeer if we cannot connect to the peer or HandshakeFailure if the remote
    disconnects before completing the handshake or if none of the sub-protocols supported by us is
    also supported by the remote.
    """
    try:
        (aes_secret,
         mac_secret,
         egress_mac,
         ingress_mac,
         reader,
         writer
         ) = await auth.handshake(remote, privkey, token)
    except (ConnectionRefusedError, OSError) as e:
        raise UnreachablePeer(e)
    peer = peer_class(
        remote=remote, privkey=privkey, reader=reader, writer=writer,
        aes_secret=aes_secret, mac_secret=mac_secret, egress_mac=egress_mac,
        ingress_mac=ingress_mac, headerdb=headerdb, network_id=network_id)
    await peer.do_p2p_handshake()
    await peer.do_sub_proto_handshake()
    return peer
Exemple #3
0
async def handshake(remote: Node, factory: 'BasePeerFactory') -> 'BasePeer':
    """Perform the auth and P2P handshakes with the given remote.

    Return an instance of the given peer_class (must be a subclass of
    BasePeer) connected to that remote in case both handshakes are
    successful and at least one of the sub-protocols supported by
    peer_class is also supported by the remote.

    Raises UnreachablePeer if we cannot connect to the peer or
    HandshakeFailure if the remote disconnects before completing the
    handshake or if none of the sub-protocols supported by us is also
    supported by the remote.
    """
    try:
        (aes_secret, mac_secret, egress_mac, ingress_mac, reader,
         writer) = await auth.handshake(remote, factory.privkey,
                                        factory.cancel_token)
    except (ConnectionRefusedError, OSError) as e:
        raise UnreachablePeer() from e
    connection = PeerConnection(
        reader=reader,
        writer=writer,
        aes_secret=aes_secret,
        mac_secret=mac_secret,
        egress_mac=egress_mac,
        ingress_mac=ingress_mac,
    )
    peer = factory.create_peer(
        remote=remote,
        connection=connection,
        inbound=False,
    )
    await peer.do_p2p_handshake()
    await peer.do_sub_proto_handshake()
    return peer
Exemple #4
0
    async def connect(cls, remote: NodeAPI,
                      private_key: datatypes.PrivateKey) -> TransportAPI:
        """Perform the auth handshake with the given remote.

        Raises UnreachablePeer if we cannot connect to the peer or
        HandshakeFailure if the remote disconnects before completing the
        handshake or if none of the sub-protocols supported by us is also
        supported by the remote.
        """
        cls.logger.debug2("Initiating auth handshake with %s", remote)
        try:
            (aes_secret, mac_secret, egress_mac, ingress_mac, reader,
             writer) = await auth.handshake(remote, private_key)
        except (ConnectionRefusedError, OSError) as e:
            raise UnreachablePeer(f"Can't reach {remote!r}") from e

        cls.logger.debug2("Completed auth handshake with %s", remote)
        return cls(
            remote=remote,
            private_key=private_key,
            reader=reader,
            writer=writer,
            aes_secret=aes_secret,
            mac_secret=mac_secret,
            egress_mac=egress_mac,
            ingress_mac=ingress_mac,
        )
Exemple #5
0
async def handshake(remote: Node, factory: 'BasePeerFactory') -> 'BasePeer':
    """Perform the auth and P2P handshakes with the given remote.

    Return an instance of the given peer_class (must be a subclass of
    BasePeer) connected to that remote in case both handshakes are
    successful and at least one of the sub-protocols supported by
    peer_class is also supported by the remote.

    Raises UnreachablePeer if we cannot connect to the peer or
    HandshakeFailure if the remote disconnects before completing the
    handshake or if none of the sub-protocols supported by us is also
    supported by the remote.
    """
    try:
        (aes_secret,
         mac_secret,
         egress_mac,
         ingress_mac,
         reader,
         writer
         ) = await auth.handshake(remote, factory.privkey, factory.cancel_token)
    except (ConnectionRefusedError, OSError) as e:
        raise UnreachablePeer(f"Can't reach {remote!r}") from e
    connection = PeerConnection(
        reader=reader,
        writer=writer,
        aes_secret=aes_secret,
        mac_secret=mac_secret,
        egress_mac=egress_mac,
        ingress_mac=ingress_mac,
    )
    peer = factory.create_peer(
        remote=remote,
        connection=connection,
        inbound=False,
    )

    try:
        await peer.do_p2p_handshake()
        await peer.do_sub_proto_handshake()
    except Exception:
        # Note: This is one of two places where we manually handle closing the
        # reader/writer connection pair in the event of an error during the
        # peer connection and handshake process.
        # See `p2p.auth.handshake` for the other.
        if not reader.at_eof():
            reader.feed_eof()
        writer.close()
        await asyncio.sleep(0)
        raise

    return peer