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

bt.runtime.Config Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2016—2021 Andrei Tomashpolskiy and individual contributors.
 *
 * 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 bt.runtime;

import bt.data.digest.SHA1Digester;
import bt.net.crypto.MSEHandshakeProcessor;
import bt.protocol.crypto.EncryptionPolicy;
import bt.service.NetworkUtil;

import java.net.InetAddress;
import java.time.Duration;
import java.util.Optional;

/**
 * Provides runtime configuration parameters.
 *
 * @since 1.0
 */
public class Config {

    private InetAddress acceptorAddress;
    private Optional peerAddress;
    private int acceptorPort;
    private Duration peerDiscoveryInterval;
    private Duration peerHandshakeTimeout;
    private Duration peerConnectionRetryInterval;
    private int peerConnectionRetryCount;
    private Duration peerConnectionTimeout;
    private Duration peerConnectionInactivityThreshold;
    private Duration trackerQueryInterval;
    private Duration trackerTimeout;
    private int maxPeerConnections;
    private int maxPeerConnectionsPerTorrent;
    private int transferBlockSize;
    private int maxTransferBlockSize;
    private int maxIOQueueSize;
    private Duration shutdownHookTimeout;
    private int numOfHashingThreads;
    private int maxConcurrentlyActivePeerConnectionsPerTorrent;
    private int maxSimultaneouslyAssignedPieces;
    private Duration maxPieceReceivingTime;
    private Duration maxMessageProcessingInterval;
    private Duration unreachablePeerBanDuration;
    private int maxPendingConnectionRequests;
    private Duration timeoutedAssignmentPeerBanDuration;
    private EncryptionPolicy encryptionPolicy;
    private int metadataExchangeBlockSize;
    private int metadataExchangeMaxSize;
    private int msePrivateKeySize;
    private boolean mseDisabled;
    private Duration mseWaitBetweenReads;
    private int numberOfPeersToRequestFromTracker;
    private int maxOutstandingRequests;
    private int networkBufferSize;
    private int hashingBufferSize;

    /**
     * Create a config with default parameters.
     *
     * @since 1.0
     */
    public Config() {
        this.acceptorAddress = NetworkUtil.getInetAddressFromNetworkInterfaces();
        this.peerAddress = Optional.empty();
        this.acceptorPort = 6891;
        this.peerDiscoveryInterval = Duration.ofSeconds(5);
        this.peerConnectionRetryInterval = Duration.ofMinutes(5);
        this.peerConnectionRetryCount = 3;
        this.peerConnectionTimeout = Duration.ofSeconds(30);
        this.peerHandshakeTimeout = Duration.ofSeconds(30);
        this.peerConnectionInactivityThreshold = Duration.ofMinutes(3);
        this.trackerQueryInterval = null; // use interval returned in tracker response by default
        this.trackerTimeout = null;
        this.maxPeerConnections = 500;
        this.maxPeerConnectionsPerTorrent = maxPeerConnections; // assume single torrent per runtime by default; change this to (maxActive * 2) maybe?
        this.transferBlockSize = 16 * 1024; // 16 KB
        this.maxTransferBlockSize = 128 * 1024; // 128 KB
        this.maxIOQueueSize = Integer.MAX_VALUE;
        this.shutdownHookTimeout = Duration.ofSeconds(30);
        this.numOfHashingThreads = 1; // do not parallelize by default
        this.maxConcurrentlyActivePeerConnectionsPerTorrent = 10;
        this.maxSimultaneouslyAssignedPieces = 3;
        this.maxPieceReceivingTime = Duration.ofSeconds(5);
        this.maxMessageProcessingInterval = Duration.ofMillis(100);
        this.unreachablePeerBanDuration = Duration.ofMinutes(30);
        this.maxPendingConnectionRequests = 50;
        this.timeoutedAssignmentPeerBanDuration = Duration.ofMinutes(1);
        this.encryptionPolicy = EncryptionPolicy.PREFER_PLAINTEXT;
        this.metadataExchangeBlockSize = 16 * 1024; // 16 KB
        this.metadataExchangeMaxSize = 2 * 1024 * 1024; // 2 MB
        this.msePrivateKeySize = 20; // 20 bytes
        this.mseDisabled = false;
        this.mseWaitBetweenReads = Duration.ofSeconds(1);
        this.numberOfPeersToRequestFromTracker = 50;
        this.maxOutstandingRequests = 250;
        this.networkBufferSize = 1 * 1024 * 1024; // 1 MB
        this.hashingBufferSize = SHA1Digester.DEFAULT_BUFFER_SIZE;
    }

    /**
     * Clone the provided config.
     *
     * @param config Config to take parameters from.
     * @since 1.0
     */
    public Config(Config config) {
        this.acceptorAddress = config.getAcceptorAddress();
        this.peerAddress = config.getPeerAddress();
        this.acceptorPort = config.getAcceptorPort();
        this.peerDiscoveryInterval = config.getPeerDiscoveryInterval();
        this.peerConnectionRetryInterval = config.getPeerConnectionRetryInterval();
        this.peerConnectionRetryCount = config.getPeerConnectionRetryCount();
        this.peerConnectionTimeout = config.getPeerConnectionTimeout();
        this.peerHandshakeTimeout = config.getPeerHandshakeTimeout();
        this.peerConnectionInactivityThreshold = config.getPeerConnectionInactivityThreshold();
        this.trackerQueryInterval = config.getTrackerQueryInterval();
        this.trackerTimeout = config.getTrackerTimeout();
        this.maxPeerConnections = config.getMaxPeerConnections();
        this.maxPeerConnectionsPerTorrent = config.getMaxPeerConnectionsPerTorrent();
        this.transferBlockSize = config.getTransferBlockSize();
        this.maxTransferBlockSize = config.getMaxTransferBlockSize();
        this.maxIOQueueSize = config.getMaxIOQueueSize();
        this.shutdownHookTimeout = config.getShutdownHookTimeout();
        this.numOfHashingThreads = config.getNumOfHashingThreads();
        this.maxConcurrentlyActivePeerConnectionsPerTorrent = config.getMaxConcurrentlyActivePeerConnectionsPerTorrent();
        this.maxSimultaneouslyAssignedPieces = config.getMaxSimultaneouslyAssignedPieces();
        this.maxPieceReceivingTime = config.getMaxPieceReceivingTime();
        this.maxMessageProcessingInterval = config.getMaxMessageProcessingInterval();
        this.unreachablePeerBanDuration = config.getUnreachablePeerBanDuration();
        this.maxPendingConnectionRequests = config.getMaxPendingConnectionRequests();
        this.timeoutedAssignmentPeerBanDuration = config.getTimeoutedAssignmentPeerBanDuration();
        this.encryptionPolicy = config.getEncryptionPolicy();
        this.metadataExchangeBlockSize = config.getMetadataExchangeBlockSize();
        this.metadataExchangeMaxSize = config.getMetadataExchangeMaxSize();
        this.msePrivateKeySize = config.getMsePrivateKeySize();
        this.mseDisabled = config.isMseDisabled();
        this.mseWaitBetweenReads = config.getMseWaitBetweenReads();
        this.numberOfPeersToRequestFromTracker = config.getNumberOfPeersToRequestFromTracker();
        this.maxOutstandingRequests = config.getMaxOutstandingRequests();
        this.networkBufferSize = config.getNetworkBufferSize();
        this.hashingBufferSize = config.getHashingBufferSize();
    }

    /**
     * @param acceptorAddress Local link that will be used by the incoming connection acceptor.
     * @since 1.0
     */
    public void setAcceptorAddress(InetAddress acceptorAddress) {
        this.acceptorAddress = acceptorAddress;
    }

    /**
     * @since 1.0
     */
    public InetAddress getAcceptorAddress() {
        return acceptorAddress;
    }

    /**
     * @return the address to send to the tracker
     * @since 1.10
     */
    public Optional getPeerAddress() {
        return peerAddress;
    }

    /**
     * Set the address to send to the tracker. Useful if the local address to accept new connections differs from the
     * remote address a user should connect to this client with for example in the case of NAT. Only supported for http
     * trackers currently. Defaults to {@link #getAcceptorAddress()}
     *
     * @param peerAddress the address to send to the tracker.
     * @since 1.10
     */
    public void setPeerAddress(InetAddress peerAddress) {
        this.peerAddress = Optional.ofNullable(peerAddress);
    }

    /**
     * @param acceptorPort Local port that will be used by the incoming connection acceptor.
     * @since 1.0
     */
    public void setAcceptorPort(int acceptorPort) {
        this.acceptorPort = acceptorPort;
    }

    /**
     * @since 1.0
     */
    public int getAcceptorPort() {
        return acceptorPort;
    }

    /**
     * @param peerDiscoveryInterval Interval at which peer sources should be queried for new peers.
     * @since 1.0
     */
    public void setPeerDiscoveryInterval(Duration peerDiscoveryInterval) {
        this.peerDiscoveryInterval = peerDiscoveryInterval;
    }

    /**
     * @since 1.0
     */
    public Duration getPeerDiscoveryInterval() {
        return peerDiscoveryInterval;
    }

    /**
     * @param peerHandshakeTimeout Time to wait for a peer's handshake.
     * @since 1.0
     */
    public void setPeerHandshakeTimeout(Duration peerHandshakeTimeout) {
        this.peerHandshakeTimeout = peerHandshakeTimeout;
    }

    /**
     * @since 1.0
     */
    public Duration getPeerHandshakeTimeout() {
        return peerHandshakeTimeout;
    }

    /**
     * @param peerConnectionRetryInterval Interval at which attempts to connect to a peer will be performed
     * @since 1.0
     */
    public void setPeerConnectionRetryInterval(Duration peerConnectionRetryInterval) {
        this.peerConnectionRetryInterval = peerConnectionRetryInterval;
    }

    /**
     * @since 1.0
     */
    public Duration getPeerConnectionRetryInterval() {
        return peerConnectionRetryInterval;
    }

    /**
     * @param peerConnectionRetryCount Max number of attempts to connect to a peer
     * @since 1.0
     */
    public void setPeerConnectionRetryCount(int peerConnectionRetryCount) {
        this.peerConnectionRetryCount = peerConnectionRetryCount;
    }

    /**
     * @since 1.0
     */
    public int getPeerConnectionRetryCount() {
        return peerConnectionRetryCount;
    }

    /**
     * @param peerConnectionTimeout Amount of time to wait for establishing of a peer connection
     * @since 1.0
     */
    public void setPeerConnectionTimeout(Duration peerConnectionTimeout) {
        this.peerConnectionTimeout = peerConnectionTimeout;
    }

    /**
     * @since 1.0
     */
    public Duration getPeerConnectionTimeout() {
        return peerConnectionTimeout;
    }

    /**
     * @param peerConnectionInactivityThreshold Amount of time after which an inactive peer connection will be dropped
     * @since 1.0
     */
    public void setPeerConnectionInactivityThreshold(Duration peerConnectionInactivityThreshold) {
        this.peerConnectionInactivityThreshold = peerConnectionInactivityThreshold;
    }

    /**
     * @since 1.0
     */
    public Duration getPeerConnectionInactivityThreshold() {
        return peerConnectionInactivityThreshold;
    }

    /**
     * @param trackerQueryInterval Interval at which trackers will be queried for peers.
     * @since 1.0
     */
    public void setTrackerQueryInterval(Duration trackerQueryInterval) {
        this.trackerQueryInterval = trackerQueryInterval;
    }

    /**
     * @since 1.0
     */
    public Duration getTrackerQueryInterval() {
        return trackerQueryInterval;
    }

    /**
     * Set the tracker/peer source timeout
     *
     * Currently used in the following contexts:
     * - HTTP trackers: used as connection timeout and SO_TIMEOUT;
     *   default is 30 seconds
     * - UDP trackers: used as an additional limit on maximal BEP-0015 timeout;
     *   formula is Math.min(3840 seconds, trackerTimeout)
     * - all ScheduledPeerSources (HTTP, UDP, DHT): used during the first (initial)
     *   peer collection as a limit on the time to wait for the collection to finish
     *   before querying the next peer source; default is 10 seconds
     *
     * @param trackerTimeout the amount of time to wait for a response from the tracker
     */
    public void setTrackerTimeout(Duration trackerTimeout) {
        this.trackerTimeout = trackerTimeout;
    }

    /**
     * Tracker/peer source timeout
     *
     * See {@link #setTrackerTimeout(Duration)} for the explanation on how this is used
     *
     * @since 1.10
     */
    public Duration getTrackerTimeout() {
        return trackerTimeout;
    }

    /**
     * @param maxPeerConnections Maximum amount of established peer connections per runtime
     *                           (all torrent processing sessions combined).
     * @since 1.0
     */
    public void setMaxPeerConnections(int maxPeerConnections) {
        this.maxPeerConnections = maxPeerConnections;
    }

    /**
     * @since 1.0
     */
    public int getMaxPeerConnections() {
        return maxPeerConnections;
    }

    /**
     * @param maxPeerConnectionsPerTorrent Maximum number of established peer connections
     *                                     within a torrent processing session.
     * @since 1.0
     */
    public void setMaxPeerConnectionsPerTorrent(int maxPeerConnectionsPerTorrent) {
        this.maxPeerConnectionsPerTorrent = maxPeerConnectionsPerTorrent;
    }

    /**
     * @since 1.0
     */
    public int getMaxPeerConnectionsPerTorrent() {
        return maxPeerConnectionsPerTorrent;
    }

    /**
     * @param transferBlockSize Network transfer block size
     * @since 1.0
     */
    public void setTransferBlockSize(int transferBlockSize) {
        this.transferBlockSize = transferBlockSize;
    }

    /**
     * @since 1.0
     */
    public int getTransferBlockSize() {
        return transferBlockSize;
    }

    /**
     * @param maxTransferBlockSize Maximum supported transfer block size.
     * @since 1.0
     */
    public void setMaxTransferBlockSize(int maxTransferBlockSize) {
        this.maxTransferBlockSize = maxTransferBlockSize;
    }

    /**
     * @since 1.0
     */
    public int getMaxTransferBlockSize() {
        return maxTransferBlockSize;
    }

    /**
     * @param maxIOQueueSize Maximum depth of I/O operations queue (read/write blocks).
     */
    public void setMaxIOQueueSize(int maxIOQueueSize) {
        this.maxIOQueueSize = maxIOQueueSize;
    }

    /**
     * @since 1.0
     */
    public int getMaxIOQueueSize() {
        return maxIOQueueSize;
    }

    /**
     * @param shutdownHookTimeout Amount of time to wait for a shutdown hook to execute before killing it
     * @since 1.0
     */
    public void setShutdownHookTimeout(Duration shutdownHookTimeout) {
        this.shutdownHookTimeout = shutdownHookTimeout;
    }

    /**
     * @since 1.0
     */
    public Duration getShutdownHookTimeout() {
        return shutdownHookTimeout;
    }

    /**
     * @param numOfHashingThreads Set this value to 2 or greater,
     *                            if verification of the torrent data should be parallelized
     * @since 1.1
     */
    public void setNumOfHashingThreads(int numOfHashingThreads) {
        this.numOfHashingThreads = numOfHashingThreads;
    }

    /**
     * @since 1.1
     */
    public int getNumOfHashingThreads() {
        return numOfHashingThreads;
    }

    /**
     * Maximum number of peer connections that are allowed to request and receive pieces.
     * Affects performance (too few or too many is bad).
     * 

* Note that this value implicitly affects when the torrent processing session enters * the so-called "endgame" mode. By default it's assumed that the endgame mode should * be activated when the number of remaining (incomplete) pieces is smaller than the * number of pending requests, which in its' turn is no greater than this value. *

* E.g. if the limit for concurrently active connections is 20, and there are in fact 20 * peers that we are downloading from at the moment, then the endgame will begin * as soon as there are 20 pieces left to download. At the same time if there are only 15 * active connections, than the endgame will begin when there are 15 pieces left. * Thus this value affects only the lower bound on the number of pieces to be left * to trigger the beginning of an endgame. * * @param maxConcurrentlyActivePeerConnectionsPerTorrent Maximum number of peer connections * that are allowed to request and receive pieces. * @since 1.1 */ public void setMaxConcurrentlyActivePeerConnectionsPerTorrent(int maxConcurrentlyActivePeerConnectionsPerTorrent) { this.maxConcurrentlyActivePeerConnectionsPerTorrent = maxConcurrentlyActivePeerConnectionsPerTorrent; } /** * @since 1.1 */ public int getMaxConcurrentlyActivePeerConnectionsPerTorrent() { return maxConcurrentlyActivePeerConnectionsPerTorrent; } /** * Set the number of pieces that are assigned to a single peer * * @param maxSimultaneouslyAssignedPieces the max number of pieces assigned to a single peer * @since 1.10 */ public void setMaxSimultaneouslyAssignedPieces(int maxSimultaneouslyAssignedPieces) { this.maxSimultaneouslyAssignedPieces = maxSimultaneouslyAssignedPieces; } /** * @since 1.10 */ public int getMaxSimultaneouslyAssignedPieces() { return maxSimultaneouslyAssignedPieces; } /** * @param maxPieceReceivingTime Limit on the amount of time it takes to receive all blocks in a piece * from a peer until this peer is considered timeouted and banned for a short * amount of time (with the piece being unassigned from this peer). * @since 1.1 */ public void setMaxPieceReceivingTime(Duration maxPieceReceivingTime) { this.maxPieceReceivingTime = maxPieceReceivingTime; } /** * @since 1.1 */ public Duration getMaxPieceReceivingTime() { return maxPieceReceivingTime; } /** * This option is related to the adaptive message processing interval feature in the message dispatcher. * The lower this value the higher the ingoing/outgoing message processing rate but also higher the CPU load. * Reasonable value (in 100..1000 ms range) greatly reduces the CPU load when there is little network activity * without compromising the overall message exchange rates. * * @param maxMessageProcessingInterval Maximum time to sleep between message processing loop iterations, in millis. * @see bt.net.MessageDispatcher * @since 1.1 */ public void setMaxMessageProcessingInterval(Duration maxMessageProcessingInterval) { this.maxMessageProcessingInterval = maxMessageProcessingInterval; } /** * @since 1.1 */ public Duration getMaxMessageProcessingInterval() { return maxMessageProcessingInterval; } /** * @param unreachablePeerBanDuration If a peer is not reachable (i.e. some kind of I/O error happens * when a connection attempt is made), then new requests to connect * to this peer will be ignored for this amount of time. * @since 1.1 */ public void setUnreachablePeerBanDuration(Duration unreachablePeerBanDuration) { this.unreachablePeerBanDuration = unreachablePeerBanDuration; } /** * @since 1.1 */ public Duration getUnreachablePeerBanDuration() { return unreachablePeerBanDuration; } /** * @param maxPendingConnectionRequests Maximum allowed number of simultaneous connection requests * (both inbound and outbound). All subsequent requests will be queued * until some of the currently pending/processed requests is completed. * @since 1.1 */ public void setMaxPendingConnectionRequests(int maxPendingConnectionRequests) { this.maxPendingConnectionRequests = maxPendingConnectionRequests; } /** * @since 1.1 */ public int getMaxPendingConnectionRequests() { return maxPendingConnectionRequests; } /** * @param timeoutedAssignmentPeerBanDuration Amount of time to keep the torrent processing session from * requesting a peer for new pieces if this peer's previous assignment * was cancelled due to a timeout. * @see #setMaxPieceReceivingTime(Duration) * @since 1.1 */ public void setTimeoutedAssignmentPeerBanDuration(Duration timeoutedAssignmentPeerBanDuration) { this.timeoutedAssignmentPeerBanDuration = timeoutedAssignmentPeerBanDuration; } /** * @since 1.1 */ public Duration getTimeoutedAssignmentPeerBanDuration() { return timeoutedAssignmentPeerBanDuration; } /** * @param encryptionPolicy Message Stream Encryption policy * @since 1.2 */ public void setEncryptionPolicy(EncryptionPolicy encryptionPolicy) { this.encryptionPolicy = encryptionPolicy; } /** * @since 1.2 */ public EncryptionPolicy getEncryptionPolicy() { return encryptionPolicy; } /** * @param metadataExchangeBlockSize BEP-9 transfer block size * @since 1.3 */ public void setMetadataExchangeBlockSize(int metadataExchangeBlockSize) { this.metadataExchangeBlockSize = metadataExchangeBlockSize; } /** * @since 1.3 */ public int getMetadataExchangeBlockSize() { return metadataExchangeBlockSize; } /** * @param metadataExchangeMaxSize Maximum allowed metadata size for BEP-9 transfer * @since 1.3 */ public void setMetadataExchangeMaxSize(int metadataExchangeMaxSize) { this.metadataExchangeMaxSize = metadataExchangeMaxSize; } /** * @since 1.3 */ public int getMetadataExchangeMaxSize() { return metadataExchangeMaxSize; } /** * @param msePrivateKeySize MSE private key size in bytes. * Allowed values are 16..512 bytes (128..4096 bits). Default is 20 bytes (160 bit). * @since 1.3 */ public void setMsePrivateKeySize(int msePrivateKeySize) { this.msePrivateKeySize = msePrivateKeySize; } /** * @since 1.3 */ public int getMsePrivateKeySize() { return msePrivateKeySize; } /** * @param mseDisabled set true to disable mse, see {@link MSEHandshakeProcessor} * @since 1.10 */ public void setMseDisabled(boolean mseDisabled) { this.mseDisabled = mseDisabled; } /** * @since 1.10 */ public boolean isMseDisabled() { return mseDisabled; } /** * @param mseWaitBetweenReads Read timeout when doing mse handshake. * In good network environment, turning down this value may decrease mse handshake time cost. * @since 1.10 */ public void setMseWaitBetweenReads(Duration mseWaitBetweenReads) { this.mseWaitBetweenReads = mseWaitBetweenReads; } /** * @since 1.10 */ public Duration getMseWaitBetweenReads() { return mseWaitBetweenReads; } /** * @param numberOfPeersToRequestFromTracker Number of peers to request from a tracker * @since 1.5 */ public void setNumberOfPeersToRequestFromTracker(int numberOfPeersToRequestFromTracker) { this.numberOfPeersToRequestFromTracker = numberOfPeersToRequestFromTracker; } /** * @since 1.5 */ public int getNumberOfPeersToRequestFromTracker() { return numberOfPeersToRequestFromTracker; } /** * @param maxOutstandingRequests Limit on the number of outstanding requests to a peer * @since 1.9 */ public void setMaxOutstandingRequests(int maxOutstandingRequests) { this.maxOutstandingRequests = maxOutstandingRequests; } /** * @since 1.9 */ public int getMaxOutstandingRequests() { return maxOutstandingRequests; } /** * @param networkBufferSize Size of send and receive network buffers (in bytes) * @since 1.9 */ public void setNetworkBufferSize(int networkBufferSize) { this.networkBufferSize = networkBufferSize; } /** * @since 1.9 */ public int getNetworkBufferSize() { return networkBufferSize; } /** * Get the digest buffer size * * @return the size of the digest buffer * @since 1.10 */ public int getHashingBufferSize() { return hashingBufferSize; } /** * Set the size of the io buffer used for reading from files to verify their digest. * * @param hashingBufferSize the size of the digest buffer * @since 1.10 */ public void setHashingBufferSize(int hashingBufferSize) { this.hashingBufferSize = hashingBufferSize; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy