Package-level declarations

Types

Link copied to clipboard
class CompactNode(val id: Sha1Hash, val endpoint: DhtEndpoint)

A single entry in a DHT compact nodes / nodes6 list: a 20-byte NodeId followed by a compact DhtEndpoint. This is the on-wire form produced by libtorrent's write_nodes_entry (src/kademlia/node.cpp), which concatenates id and write_endpoint(ep) for each node.

Link copied to clipboard

Encode/decode of the compact nodes strings that BEP-5 queries return: the counterpart to libtorrent's write_nodes_entry and the inline decode loops in find_data / the routing table's read_nodes. The IPv4 form ("n4"/nodes, 26-byte records) and the IPv6 form ("n6"/nodes6, 38-byte records) are encoded here separately because the record width is fixed per family.

Link copied to clipboard
class DhtEndpoint(val address: ByteArray, val port: Int)

A network endpoint (address + UDP/TCP port) as it appears inside DHT messages: the pure-Kotlin stand-in for the udp::endpoint / tcp::endpoint that libtorrent serialises with aux::write_endpoint / aux::read_v4_endpoint (include/libtorrent/socket_io.hpp).

Link copied to clipboard
sealed class DhtItem

A DHT data item, the port of class dht::item (item.cpp, item.hpp). An item is either immutable (target = SHA-1 of the bencoded value, BEP-44 §"Immutable items") or mutable (target = SHA-1(public key + salt), signed by an ed25519 key, BEP-44 §"Mutable items").

Link copied to clipboard
object DhtItems

Free functions mirroring the file-scope helpers in src/kademlia/item.cpp: item_target_id, sign_mutable_item, verify_mutable_item.

Link copied to clipboard

The fixed-size ed25519 / sequence-number value types used by BEP-44 mutable DHT items. This is the port of libtorrent's dht::public_key, dht::secret_key, dht::signature and dht::sequence_number (include/libtorrent/kademlia/types.hpp).

Link copied to clipboard
sealed class DhtMessage

The KRPC message model and codec for the BitTorrent DHT: a pure-Kotlin port of the message-building and -parsing code spread across libtorrent's src/kademlia/node.cpp (incoming_request, the per-query response builders, and the single-bucket-refresh / ping query builders), find_data.cpp, get_peers.cpp, get_item.cpp, put_data.cpp and msg.cpp.

Link copied to clipboard
class DhtStorage(val maxPeersPerTorrent: Int = DEFAULT_MAX_PEERS, val maxItems: Int = DEFAULT_MAX_ITEMS, val maxTorrents: Int = DEFAULT_MAX_TORRENTS)

In-memory DHT data store. This is a pure-Kotlin port of libtorrent's dht_default_storage (src/kademlia/dht_storage.cpp). It holds the three things a DHT node serves:

Link copied to clipboard

An immutable BEP-44 item, item(entry v) in libtorrent. Its target is the SHA-1 of the bencoded value, so the value cannot change without changing the key.

Link copied to clipboard
class KeyDesc(val name: String, val type: BdecodeNode.Type, val size: Int = 0, val flags: Int = 0)

A single required or optional key in a DHT message schema. This is the port of struct key_desc_t (include/libtorrent/kademlia/msg.hpp). Together with verifyMessage this reproduces libtorrent's verify_message_impl (src/kademlia/msg.cpp): a table of these describes the keys a query/response must contain, their bencode type, optional exact size constraints, and nesting flags.

Link copied to clipboard

A mutable BEP-44 item: the signed variant of dht::item. It holds the ed25519 public key, a salt (possibly empty), a 64-bit sequence number and a signature over DhtItems.signMutableItem's canonical buffer.

Link copied to clipboard
class NodeEntry

One node in the DHT routing table: the pure-Kotlin port of libtorrent's node_entry (include/libtorrent/kademlia/node_entry.hpp, src/kademlia/node_entry.cpp).

Link copied to clipboard
class RoutingTable(id: Sha1Hash, val bucketSize: Int, val settings: RoutingTableSettings = RoutingTableSettings())

The Kademlia k-bucket routing table. This is the pure-Kotlin port of libtorrent's routing_table (include/libtorrent/kademlia/routing_table.hpp, src/kademlia/routing_table.cpp).

Link copied to clipboard
data class RoutingTableSettings(val maxFailCount: Int = 20, val restrictRoutingIps: Boolean = true, val extendedRoutingTable: Boolean = true, val preferVerifiedNodeIds: Boolean = true, val enforceNodeId: Boolean = false)

The DHT routing knobs the table reads, mirroring the five relevant settings_pack entries with libtorrent's exact defaults (see src/settings_pack.cpp). Pulling them into a small value object keeps the routing table decoupled from KiteTorrent's general SettingsPack, which does not (yet) carry DHT fields.

Link copied to clipboard

Result of verifyMessage: success plus the extracted nodes, or a failure reason.

Properties

Link copied to clipboard
const val NODE_ID_SIZE: Int

The number of bytes in a NodeId (160 bits).

Functions

Link copied to clipboard
fun allInSameBucket(b: List<NodeEntry>, nodeId: Sha1Hash, bucketIndex: Int): Boolean

Would every node in b, plus the candidate nodeId, fall on the same side of the split at bit bucketIndex? If so, splitting the bucket gains nothing. Port of bool all_in_same_bucket(span<node_entry const>, node_id const&, int).

Link copied to clipboard
fun classifyPrefix(bucketIdx: Int, lastBucket: Boolean, bucketSizeLimit: Int, nid: Sha1Hash): Int

Classify which "sub-branch" of a bucket nid falls into, using the few bits after the bucket's shared prefix. Port of std::uint8_t classify_prefix(int bucket_idx, bool last_bucket, int bucket_size, node_id nid).

Link copied to clipboard

true if two IPs are "too close" to share a DHT lookup. Port of bool compare_ip_cidr(address const&, address const&): IPv6 addresses in the same /64 and IPv4 addresses in the same /24 are considered too close. Mixed families are never close.

Link copied to clipboard

true iff distance(n1, ref) < distance(n2, ref), i.e. n1 is strictly closer to ref than n2 is. Port of bool compare_ref(...). This is the comparator RoutingTable.findNode uses to order results by closeness to the target.

Link copied to clipboard

The distance between two nodes under the Kademlia XOR metric: distance(n1, n2) = n1 ^ n2. Direct port of node_id distance(...).

Link copied to clipboard

Returns n such that 2^n <= distance(n1, n2) < 2^(n+1). It is useful for finding which bucket a node belongs to. The value is the number of trailing bits after the shared bit prefix of n1 and n2; if the very first bits differ it is 159 (see the note below).

Link copied to clipboard
fun generateId(ip: PeerAddress, random: Random = Random.Default): Sha1Hash

Generate a fully random BEP 42 secure node id for ip, choosing r at random. Port of node_id generate_id(address const& ip): return generate_id_impl(ip, random(0xffffffff));. Only the low byte of r (and its low 3 bits, via the CRC) matter, so we draw a random 8-bit r.

Link copied to clipboard
fun generateIdImpl(ip: PeerAddress, r: Int, random: Random = Random.Default): Sha1Hash

Generate a BEP 42 ("secure") node id from an external IP address and a chosen 8-bit "r" value, the deterministic core of id generation. Faithful port of node_id generate_id_impl(address const& ip_, std::uint32_t r).

Link copied to clipboard

A node id whose top bits bits are 1 and the rest 0. Port of node_id generate_prefix_mask(int bits). bits must be in 0..160.

Link copied to clipboard
fun generateRandomId(random: Random = Random.Default): Sha1Hash

A fully random 160-bit node id, with no IP binding. Port of node_id generate_random_id() (which hashes 20 random bytes; the SHA-1 there is just a whitening step over an already-random buffer, so 20 fresh random bytes are an equivalent uniform 160-bit value).

Link copied to clipboard
fun matchingPrefix(nid: Sha1Hash, mask: Int, prefix: Int, offset: Int): Boolean

true iff, after shifting nid left by offset bits, the top byte ANDed with mask equals prefix. Port of bool matching_prefix(node_id const& nid, int mask, int prefix, int offset).

Link copied to clipboard

The minimum distanceExp from n1 to any id in ids. Port of int min_distance_exp(...). ids must be non-empty (libtorrent asserts it). The seed value 160 mirrors the upstream constant (see distanceExp for why).

Link copied to clipboard

true if at least two-thirds of the bucket's nodes are verified. Port of bool mostly_verified_nodes(bucket_t const&):

Link copied to clipboard
fun verifyId(nid: Sha1Hash, sourceIp: PeerAddress): Boolean

Verify that nid is a valid secure id for a node observed at sourceIp. Port of bool verify_id(node_id const& nid, address const& source_ip).

Link copied to clipboard

Verify a DHT message against a schema and extract its keys. This is a faithful port of verify_message_impl (src/kademlia/msg.cpp).