com.turn.ttorrent.client.io.PeerHandshakeMessage.java Source code

Java tutorial

Introduction

Here is the source code for com.turn.ttorrent.client.io.PeerHandshakeMessage.java

Source

/*
 * Copyright 2014 shevek.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.turn.ttorrent.client.io;

import com.turn.ttorrent.common.Torrent;
import com.turn.ttorrent.common.SuppressWarnings;
import io.netty.buffer.ByteBuf;
import java.util.Arrays;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import org.apache.commons.io.Charsets;

/**
 *
 * @author shevek
 */
public class PeerHandshakeMessage extends PeerMessage {

    public static final int BASE_HANDSHAKE_LENGTH = 49;
    private static final byte[] BITTORRENT_PROTOCOL_IDENTIFIER = "BitTorrent protocol"
            .getBytes(Torrent.BYTE_ENCODING);
    private byte[] protocolName;
    private final byte[] reserved = new byte[8];
    private byte[] infoHash; // 20
    private byte[] peerId; // 20

    public PeerHandshakeMessage() {
    }

    @SuppressWarnings("EI_EXPOSE_REP2")
    public PeerHandshakeMessage(@Nonnull byte[] infoHash, @Nonnull byte[] peerId) {
        if (infoHash.length != 20)
            throw new IllegalArgumentException("InfoHash length should be 20, not " + infoHash.length);
        if (peerId.length != 20)
            throw new IllegalArgumentException("PeerId length should be 20, not " + peerId.length);
        this.protocolName = BITTORRENT_PROTOCOL_IDENTIFIER;
        this.infoHash = infoHash;
        this.peerId = peerId;
    }

    @Override
    public Type getType() {
        return Type.HANDSHAKE;
    }

    @SuppressWarnings("EI_EXPOSE_REP2")
    public byte[] getInfoHash() {
        return infoHash;
    }

    @SuppressWarnings("EI_EXPOSE_REP2")
    public byte[] getPeerId() {
        return peerId;
    }

    @Override
    public void fromWire(ByteBuf in) {
        int pstrlen = in.readUnsignedByte();
        if (pstrlen < 0 || in.readableBytes() < BASE_HANDSHAKE_LENGTH + pstrlen - 1)
            throw new IllegalArgumentException("Incorrect handshake message length (pstrlen=" + pstrlen + ") !");

        // Check the protocol identification string
        protocolName = new byte[pstrlen];
        in.readBytes(protocolName);
        if (!Arrays.equals(protocolName, BITTORRENT_PROTOCOL_IDENTIFIER))
            throw new IllegalArgumentException("Unknown protocol " + new String(protocolName, Charsets.ISO_8859_1));

        // Ignore reserved bytes
        in.readBytes(reserved);

        infoHash = new byte[20];
        in.readBytes(infoHash);
        peerId = new byte[20];
        in.readBytes(peerId);
    }

    @Override
    public void toWire(ByteBuf out) {
        out.writeByte(protocolName.length);
        out.writeBytes(protocolName);
        out.writeBytes(reserved);
        out.writeBytes(infoHash);
        out.writeBytes(peerId);
    }

    private static String toHex(@CheckForNull byte[] data) {
        if (data == null)
            return null;
        return Torrent.byteArrayToHexString(data);
    }

    private static String toText(@CheckForNull byte[] data) {
        if (data == null)
            return null;
        return Torrent.byteArrayToText(data);
    }

    @Override
    public String toString() {
        return super.toString() + " P=" + toText(getPeerId()) + " T=" + toHex(getInfoHash());
    }
}