Search in sources :

Example 6 with BDecoder

use of org.klomp.snark.bencode.BDecoder in project i2p.i2p by i2p.

the class ExtensionHandler method handleHandshake.

private static void handleHandshake(Peer peer, PeerListener listener, byte[] bs, Log log) {
    if (log.shouldLog(Log.DEBUG))
        log.debug("Got handshake msg from " + peer);
    try {
        // this throws NPE on missing keys
        InputStream is = new ByteArrayInputStream(bs);
        BDecoder dec = new BDecoder(is);
        BEValue bev = dec.bdecodeMap();
        Map<String, BEValue> map = bev.getMap();
        peer.setHandshakeMap(map);
        Map<String, BEValue> msgmap = map.get("m").getMap();
        if (log.shouldLog(Log.DEBUG))
            log.debug("Peer " + peer + " supports extensions: " + msgmap.keySet());
        // if (msgmap.get(TYPE_PEX) != null) {
        // if (log.shouldLog(Log.DEBUG))
        // log.debug("Peer supports PEX extension: " + peer);
        // // peer state calls peer listener calls sendPEX()
        // }
        // if (msgmap.get(TYPE_DHT) != null) {
        // if (log.shouldLog(Log.DEBUG))
        // log.debug("Peer supports DHT extension: " + peer);
        // // peer state calls peer listener calls sendDHT()
        // }
        MagnetState state = peer.getMagnetState();
        if (msgmap.get(TYPE_METADATA) == null) {
            if (log.shouldLog(Log.DEBUG))
                log.debug("Peer does not support metadata extension: " + peer);
            // drop if we need metainfo and we haven't found anybody yet
            synchronized (state) {
                if (!state.isInitialized()) {
                    if (log.shouldLog(Log.DEBUG))
                        log.debug("Dropping peer, we need metadata! " + peer);
                    peer.disconnect();
                }
            }
            return;
        }
        BEValue msize = map.get("metadata_size");
        if (msize == null) {
            if (log.shouldLog(Log.DEBUG))
                log.debug("Peer does not have the metainfo size yet: " + peer);
            // drop if we need metainfo and we haven't found anybody yet
            synchronized (state) {
                if (!state.isInitialized()) {
                    if (log.shouldLog(Log.DEBUG))
                        log.debug("Dropping peer, we need metadata! " + peer);
                    peer.disconnect();
                }
            }
            return;
        }
        int metaSize = msize.getInt();
        if (log.shouldLog(Log.DEBUG))
            log.debug("Got the metainfo size: " + metaSize);
        int remaining;
        synchronized (state) {
            if (state.isComplete())
                return;
            if (state.isInitialized()) {
                if (state.getSize() != metaSize) {
                    if (log.shouldLog(Log.DEBUG))
                        log.debug("Wrong metainfo size " + metaSize + " from: " + peer);
                    peer.disconnect();
                    return;
                }
            } else {
                // initialize it
                if (metaSize > MAX_METADATA_SIZE) {
                    if (log.shouldLog(Log.DEBUG))
                        log.debug("Huge metainfo size " + metaSize + " from: " + peer);
                    peer.disconnect(false);
                    return;
                }
                if (log.shouldLog(Log.INFO))
                    log.info("Initialized state, metadata size = " + metaSize + " from " + peer);
                state.initialize(metaSize);
            }
            remaining = state.chunksRemaining();
        }
        // send requests for chunks
        int count = Math.min(remaining, PARALLEL_REQUESTS);
        for (int i = 0; i < count; i++) {
            int chk;
            synchronized (state) {
                chk = state.getNextRequest();
            }
            if (log.shouldLog(Log.INFO))
                log.info("Request chunk " + chk + " from " + peer);
            sendRequest(peer, chk);
        }
    } catch (Exception e) {
        if (log.shouldLog(Log.WARN))
            log.warn("Handshake exception from " + peer, e);
    }
}
Also used : ByteArrayInputStream(java.io.ByteArrayInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) BDecoder(org.klomp.snark.bencode.BDecoder) BEValue(org.klomp.snark.bencode.BEValue)

Example 7 with BDecoder

use of org.klomp.snark.bencode.BDecoder in project i2p.i2p by i2p.

the class ExtensionHandler method handleComment.

/**
 * Handle comment request and response
 *
 * Ref: https://blinkenlights.ch/ccms/software/bittorrent.html
 * Ref: https://github.com/adrian-bl/bitflu/blob/3cb7fe887dbdea8132e4fa36fbbf5f26cf992db3/plugins/Bitflu/20_DownloadBitTorrent.pm#L3403
 * @since 0.9.31
 */
private static void handleComment(Peer peer, PeerListener listener, byte[] bs, Log log) {
    if (log.shouldLog(Log.DEBUG))
        log.debug("Got comment msg from " + peer);
    try {
        InputStream is = new ByteArrayInputStream(bs);
        BDecoder dec = new BDecoder(is);
        BEValue bev = dec.bdecodeMap();
        Map<String, BEValue> map = bev.getMap();
        int type = map.get("msg_type").getInt();
        if (type == 0) {
            // request
            int num = 20;
            BEValue b = map.get("num");
            if (b != null)
                num = b.getInt();
            listener.gotCommentReq(peer, num);
        } else if (type == 1) {
            // response
            List<BEValue> list = map.get("comments").getList();
            if (list.isEmpty())
                return;
            List<Comment> comments = new ArrayList<Comment>(list.size());
            long now = I2PAppContext.getGlobalContext().clock().now();
            for (BEValue li : list) {
                Map<String, BEValue> m = li.getMap();
                String owner = m.get("owner").getString();
                String text = m.get("text").getString();
                // 0-5 range for rating is enforced by Comment constructor
                int rating = m.get("like").getInt();
                long time = now - (Math.max(0, m.get("timestamp").getInt()) * 1000L);
                Comment c = new Comment(text, owner, rating, time, false);
                comments.add(c);
            }
            listener.gotComments(peer, comments);
        } else {
            if (log.shouldLog(Log.INFO))
                log.info("Unknown comment msg type " + type + " from " + peer);
        }
    } catch (Exception e) {
        if (log.shouldLog(Log.INFO))
            log.info("Comment msg exception from " + peer, e);
    // peer.disconnect(false);
    }
}
Also used : Comment(org.klomp.snark.comments.Comment) ByteArrayInputStream(java.io.ByteArrayInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) BDecoder(org.klomp.snark.bencode.BDecoder) ArrayList(java.util.ArrayList) List(java.util.List) BEValue(org.klomp.snark.bencode.BEValue) HashMap(java.util.HashMap) Map(java.util.Map)

Example 8 with BDecoder

use of org.klomp.snark.bencode.BDecoder in project i2p.i2p by i2p.

the class ExtensionHandler method handleDHT.

/**
 * Receive the DHT port numbers
 * @since DHT
 */
private static void handleDHT(Peer peer, PeerListener listener, byte[] bs, Log log) {
    if (log.shouldLog(Log.DEBUG))
        log.debug("Got DHT msg from " + peer);
    try {
        InputStream is = new ByteArrayInputStream(bs);
        BDecoder dec = new BDecoder(is);
        BEValue bev = dec.bdecodeMap();
        Map<String, BEValue> map = bev.getMap();
        int qport = map.get("port").getInt();
        int rport = map.get("rport").getInt();
        listener.gotPort(peer, qport, rport);
    } catch (Exception e) {
        if (log.shouldLog(Log.INFO))
            log.info("DHT msg exception from " + peer, e);
    // peer.disconnect(false);
    }
}
Also used : ByteArrayInputStream(java.io.ByteArrayInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) BDecoder(org.klomp.snark.bencode.BDecoder) BEValue(org.klomp.snark.bencode.BEValue)

Aggregations

BDecoder (org.klomp.snark.bencode.BDecoder)8 BEValue (org.klomp.snark.bencode.BEValue)8 ByteArrayInputStream (java.io.ByteArrayInputStream)7 InputStream (java.io.InputStream)7 ArrayList (java.util.ArrayList)3 HashMap (java.util.HashMap)3 IOException (java.io.IOException)2 List (java.util.List)2 Map (java.util.Map)2 InvalidBEncodingException (org.klomp.snark.bencode.InvalidBEncodingException)2 NoSuchElementException (java.util.NoSuchElementException)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 I2PSessionException (net.i2p.client.I2PSessionException)1 I2PInvalidDatagramException (net.i2p.client.datagram.I2PInvalidDatagramException)1 DataFormatException (net.i2p.data.DataFormatException)1 Comment (org.klomp.snark.comments.Comment)1