Files
swift-torrent/Sources/SwiftTorrent/DHT/DHTStorage.swift
T
Chad Paulson 6c8c581517 Implement SwiftTorrent: pure Swift BitTorrent library
Full BEP-3 peer wire protocol, BEP-5 DHT, BEP-15 UDP trackers,
magnet link support, bencode serialization, rarest-first piece
selection, and async session management using SwiftNIO and
swift-crypto. Includes 64 passing unit tests.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 04:17:43 -06:00

56 lines
1.9 KiB
Swift

import Foundation
/// Storage for DHT peer announcements with expiration.
public struct DHTStorage: Sendable {
private var peerStore: [Data: [PeerEntry]] // info_hash -> peers
private let maxPeersPerHash: Int
private let expirationInterval: TimeInterval
public init(maxPeersPerHash: Int = 100, expirationInterval: TimeInterval = 30 * 60) {
self.peerStore = [:]
self.maxPeersPerHash = maxPeersPerHash
self.expirationInterval = expirationInterval
}
/// Store a peer for an info hash.
public mutating func addPeer(infoHash: Data, address: String, port: UInt16) {
let entry = PeerEntry(address: address, port: port, addedAt: Date())
var peers = peerStore[infoHash] ?? []
// Remove existing entry for same address:port
peers.removeAll { $0.address == address && $0.port == port }
peers.append(entry)
// Trim to max
if peers.count > maxPeersPerHash {
peers = Array(peers.suffix(maxPeersPerHash))
}
peerStore[infoHash] = peers
}
/// Get peers for an info hash.
public func getPeers(infoHash: Data) -> [(String, UInt16)] {
let cutoff = Date().addingTimeInterval(-expirationInterval)
return (peerStore[infoHash] ?? [])
.filter { $0.addedAt > cutoff }
.map { ($0.address, $0.port) }
}
/// Remove expired entries.
public mutating func removeExpired() {
let cutoff = Date().addingTimeInterval(-expirationInterval)
for (hash, peers) in peerStore {
let filtered = peers.filter { $0.addedAt > cutoff }
if filtered.isEmpty {
peerStore.removeValue(forKey: hash)
} else {
peerStore[hash] = filtered
}
}
}
private struct PeerEntry: Sendable {
let address: String
let port: UInt16
let addedAt: Date
}
}