All Downloads are FREE. Search and download functionalities are using the official Maven repository.

bt.protocol.extended.ExtendedHandshakeFactory Maven / Gradle / Ivy

There is a newer version: 1.10
Show newest version
package bt.protocol.extended;

import bt.bencoding.model.BEInteger;
import bt.bencoding.model.BEString;
import bt.metainfo.TorrentId;
import bt.protocol.IExtendedHandshakeFactory;
import bt.protocol.crypto.EncryptionPolicy;
import bt.runtime.Config;
import bt.service.ApplicationService;
import bt.torrent.TorrentRegistry;
import com.google.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigInteger;
import java.nio.charset.Charset;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 *

Note that this class implements a service. * Hence, is not a part of the public API and is a subject to change.

*/ public class ExtendedHandshakeFactory implements IExtendedHandshakeFactory { private static final Logger LOGGER = LoggerFactory.getLogger(ExtendedHandshakeFactory.class); private static final String ENCRYPTION_PROPERTY = "e"; private static final String TCPPORT_PROPERTY = "p"; private static final String VERSION_PROPERTY = "v"; private static final String UT_METADATA_SIZE_PROPERTY = "metadata_size"; private static final String VERSION_TEMPLATE = "Bt %s"; private final TorrentRegistry torrentRegistry; private final ExtendedMessageTypeMapping messageTypeMapping; private final ApplicationService applicationService; private final EncryptionPolicy encryptionPolicy; private final int tcpAcceptorPort; private final ConcurrentMap extendedHandshakes; @Inject public ExtendedHandshakeFactory(TorrentRegistry torrentRegistry, ExtendedMessageTypeMapping messageTypeMapping, ApplicationService applicationService, Config config) { this.torrentRegistry = torrentRegistry; this.messageTypeMapping = messageTypeMapping; this.applicationService = applicationService; this.encryptionPolicy = config.getEncryptionPolicy(); this.tcpAcceptorPort = config.getAcceptorPort(); this.extendedHandshakes = new ConcurrentHashMap<>(); } @Override public ExtendedHandshake getHandshake(TorrentId torrentId) { ExtendedHandshake handshake = extendedHandshakes.get(torrentId); if (handshake == null) { handshake = buildHandshake(torrentId); ExtendedHandshake existing = extendedHandshakes.putIfAbsent(torrentId, handshake); if (existing != null) { handshake = existing; } } return handshake; } private ExtendedHandshake buildHandshake(TorrentId torrentId) { ExtendedHandshake.Builder builder = ExtendedHandshake.builder(); switch (encryptionPolicy) { case REQUIRE_PLAINTEXT: case PREFER_PLAINTEXT: { builder.property(ENCRYPTION_PROPERTY, new BEInteger(null, BigInteger.ZERO)); } case PREFER_ENCRYPTED: case REQUIRE_ENCRYPTED: { builder.property(ENCRYPTION_PROPERTY, new BEInteger(null, BigInteger.ONE)); } default: { // do nothing } } builder.property(TCPPORT_PROPERTY, new BEInteger(null, BigInteger.valueOf(tcpAcceptorPort))); torrentRegistry.getTorrent(torrentId).ifPresent(torrent -> { int metadataSize = torrent.getSource().getExchangedMetadata().length; builder.property(UT_METADATA_SIZE_PROPERTY, new BEInteger(null, BigInteger.valueOf(metadataSize))); }); String version; try { version = getVersion(); } catch (Exception e) { LOGGER.error("Failed to get version", e); version = getDefaultVersion(); } builder.property(VERSION_PROPERTY, new BEString(version.getBytes(Charset.forName("UTF-8")))); messageTypeMapping.visitMappings(builder::addMessageType); return builder.build(); } protected String getVersion() { return String.format(VERSION_TEMPLATE, applicationService.getVersion()); } private String getDefaultVersion() { return String.format(VERSION_TEMPLATE, "(unknown version)"); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy