org.aotorrent.client.InboundHandshakeHandler.java Source code

Java tutorial

Introduction

Here is the source code for org.aotorrent.client.InboundHandshakeHandler.java

Source

/*
 * Copyright 2014 Napolov Dmitry
 *
 * 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 org.aotorrent.client;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.aotorrent.common.TorrentEngine;
import org.aotorrent.common.connection.PeerConnection;
import org.aotorrent.common.protocol.peer.HandshakeRequest;
import org.aotorrent.common.protocol.peer.PeerRequest;
import org.apache.commons.codec.binary.Hex;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.atomic.AtomicBoolean;

/**
 * @author dmitry 16.07.14 1:18
 */
class InboundHandshakeHandler extends ChannelInboundHandlerAdapter {
    private static final Logger LOGGER = LoggerFactory.getLogger(InboundHandshakeHandler.class);

    private final TorrentClient client;
    private final AtomicBoolean handshakeDone = new AtomicBoolean();

    public InboundHandshakeHandler(TorrentClient client) {
        this.client = client;
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        final ByteBuf buf = (ByteBuf) msg;

        if (handshakeDone.get()) {
            super.channelRead(ctx, msg);
            return;
        }

        try {
            HandshakeRequest handshakeRequest = new HandshakeRequest(buf);

            final String hexInfoHash = Hex.encodeHexString(handshakeRequest.getInfoHash());
            final TorrentEngine torrentEngine = client.getEngine(hexInfoHash);

            if (torrentEngine != null) {
                final PeerRequest peerHandshake = new HandshakeRequest(torrentEngine.getInfoHash(),
                        torrentEngine.getPeerId());
                ctx.write(peerHandshake.toTransmit());
                ctx.flush();

                PeerConnection peerConnection = new PeerConnection(torrentEngine, ctx);
                ctx.pipeline().addFirst("trafficCounter", torrentEngine.getCounter());
                ctx.pipeline().addLast("peerConnection", peerConnection);
                ctx.pipeline().remove(this);

                handshakeDone.set(true);
                LOGGER.info("Handshake done");

                ByteBuf out = ((ByteBuf) msg).copy();
                ctx.fireChannelRead(out);
                peerConnection.sendBitField();
            } else {
                LOGGER.info("Peer want to exchange torrent that we haven't");
                ctx.close();
            }
        } finally {
            buf.release();
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        LOGGER.error("Handshake failed: ", cause);
    }
}