Ejemplo n.º 1
0
  /**
   * Validate an expected handshake on a connection.
   *
   * <p>Reads an expected handshake message from the given connected socket, parses it and validates
   * that the torrent hash_info corresponds to the torrent we're sharing, and that the peerId
   * matches the peer ID we expect to see coming from the remote peer.
   *
   * @param socket The connected socket to the remote peer.
   * @param peerId The peer ID we expect in the handshake. If <em>null</em>, any peer ID is accepted
   *     (this is the case for incoming connections).
   * @return The validated handshake message object.
   */
  private Handshake validateHandshake(Socket socket, byte[] peerId)
      throws IOException, ParseException {
    InputStream is = socket.getInputStream();

    // Read the handshake from the wire
    int pstrlen = is.read();
    byte[] data = new byte[Handshake.BASE_HANDSHAKE_LENGTH + pstrlen];
    data[0] = (byte) pstrlen;
    is.read(data, 1, data.length - 1);

    // Parse and check the handshake
    Handshake hs = Handshake.parse(ByteBuffer.wrap(data));
    if (!Arrays.equals(hs.getInfoHash(), this.torrent.getInfoHash())) {
      throw new ParseException(
          "Handshake for unknow torrent "
              + Torrent.byteArrayToHexString(hs.getInfoHash())
              + " from "
              + this.socketRepr(socket)
              + ".",
          pstrlen + 9);
    }

    if (peerId != null && !Arrays.equals(hs.getPeerId(), peerId)) {
      throw new ParseException(
          "Announced peer ID "
              + Torrent.byteArrayToHexString(hs.getPeerId())
              + " did not match expected peer ID "
              + Torrent.byteArrayToHexString(peerId)
              + ".",
          pstrlen + 29);
    }

    return hs;
  }
Ejemplo n.º 2
0
    @Override
    public void run() {
      Socket socket = new Socket();
      InetSocketAddress address = new InetSocketAddress(this.peer.getIp(), this.peer.getPort());

      try {
        logger.info("Connecting to {}...", this.peer);
        socket.connect(address, 3 * 1000);

        this.handler.sendHandshake(socket);
        Handshake hs =
            this.handler.validateHandshake(
                socket, (this.peer.hasPeerId() ? this.peer.getPeerId().array() : null));
        logger.info(
            "Handshaked with {}, peer ID is {}.",
            this.peer,
            Torrent.byteArrayToHexString(hs.getPeerId()));
        this.handler.fireNewPeerConnection(socket, hs.getPeerId());
      } catch (IOException ioe) {
        try {
          socket.close();
        } catch (IOException e) {
        }
        this.handler.fireFailedConnection(this.peer, ioe);
      } catch (ParseException pe) {
        try {
          socket.close();
        } catch (IOException e) {
        }
        this.handler.fireFailedConnection(this.peer, pe);
      }
    }