Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for BTv2 magnet links #72

Merged
merged 1 commit into from
Jan 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/dht/examples/dht.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ async fn main() -> anyhow::Result<()> {
.nth(1)
.expect("first argument should be a magnet link");
let magnet = Magnet::parse(&magnet).unwrap();
let info_hash = magnet.info_hash;
let info_hash = magnet.as_id20().context("Supplied magnet link didn't contain a BTv1 infohash")?;

tracing_subscriber::fmt::init();

Expand Down
4 changes: 2 additions & 2 deletions crates/dht/src/bprotocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::{

use bencode::{ByteBuf, ByteString};
use clone_to_owned::CloneToOwned;
use librqbit_core::id20::Id20;
use librqbit_core::hash_id::Id20;
use serde::{
de::{IgnoredAny, Unexpected},
Deserialize, Deserializer, Serialize,
Expand Down Expand Up @@ -229,7 +229,7 @@ impl<'de> Deserialize<'de> for CompactNodeInfo {
let ip = Ipv4Addr::new(chunk[20], chunk[21], chunk[22], chunk[23]);
let port = ((chunk[24] as u16) << 8) + chunk[25] as u16;
buf.push(Node {
id: Id20(node_id),
id: Id20::new(node_id),
addr: SocketAddrV4::new(ip, port),
})
}
Expand Down
2 changes: 1 addition & 1 deletion crates/dht/src/dht.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use futures::{stream::FuturesUnordered, Stream, StreamExt, TryFutureExt};

use leaky_bucket::RateLimiter;
use librqbit_core::{
id20::Id20,
hash_id::Id20,
peer_id::generate_peer_id,
spawn_utils::{spawn, spawn_with_cancel},
};
Expand Down
2 changes: 1 addition & 1 deletion crates/dht/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use std::time::Duration;

pub use crate::dht::DhtStats;
pub use crate::dht::{DhtConfig, DhtState, RequestPeersStream};
pub use librqbit_core::id20::Id20;
pub use librqbit_core::hash_id::Id20;
pub use persistence::{PersistentDht, PersistentDhtConfig};

pub type Dht = Arc<DhtState>;
Expand Down
2 changes: 1 addition & 1 deletion crates/dht/src/peer_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::{

use bencode::ByteString;
use chrono::{DateTime, Utc};
use librqbit_core::id20::Id20;
use librqbit_core::hash_id::Id20;
use parking_lot::RwLock;
use rand::RngCore;
use serde::{
Expand Down
20 changes: 10 additions & 10 deletions crates/dht/src/routing_table.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{net::SocketAddr, time::Instant};

use librqbit_core::id20::Id20;
use librqbit_core::hash_id::Id20;
use rand::RngCore;
use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer};
use tracing::{debug, trace};
Expand Down Expand Up @@ -132,7 +132,7 @@ impl<'a> Iterator for BucketTreeIterator<'a> {
pub fn generate_random_id(start: &Id20, bits: u8) -> Id20 {
let mut data = [0u8; 20];
rand::thread_rng().fill_bytes(&mut data);
let mut data = Id20(data);
let mut data = Id20::new(data);
let remaining_bits = 160 - bits;
for bit in 0..remaining_bits {
data.set_bit(bit, start.get_bit(bit));
Expand Down Expand Up @@ -199,8 +199,8 @@ impl BucketTree {
BucketTree {
data: vec![BucketTreeNode {
bits: 160,
start: Id20([0u8; 20]),
end_inclusive: Id20([0xff; 20]),
start: Id20::new([0u8; 20]),
end_inclusive: Id20::new([0xff; 20]),
data: BucketTreeNodeData::Leaf(Default::default()),
}],
size: 0,
Expand Down Expand Up @@ -583,7 +583,7 @@ mod tests {
str::FromStr,
};

use librqbit_core::id20::Id20;
use librqbit_core::hash_id::Id20;
use rand::Rng;

use crate::routing_table::compute_split_start_end;
Expand All @@ -592,8 +592,8 @@ mod tests {

#[test]
fn compute_split_start_end_root() {
let start = Id20([0u8; 20]);
let end = Id20([0xff; 20]);
let start = Id20::new([0u8; 20]);
let end = Id20::new([0xff; 20]);
assert_eq!(
compute_split_start_end(start, end, 160),
(
Expand All @@ -612,7 +612,7 @@ mod tests {
#[test]
fn compute_split_start_end_second_split() {
let start = Id20::from_str("8000000000000000000000000000000000000000").unwrap();
let end = Id20([0xff; 20]);
let end = Id20::new([0xff; 20]);
assert_eq!(
compute_split_start_end(start, end, 159),
(
Expand All @@ -631,7 +631,7 @@ mod tests {
#[test]
fn compute_split_start_end_3() {
let start = Id20::from_str("8000000000000000000000000000000000000000").unwrap();
let end = Id20([0xff; 20]);
let end = Id20::new([0xff; 20]);
assert_eq!(
compute_split_start_end(start, end, 159),
(
Expand All @@ -650,7 +650,7 @@ mod tests {
fn random_id_20() -> Id20 {
let mut id20 = [0u8; 20];
rand::thread_rng().fill(&mut id20);
Id20(id20)
Id20::new(id20)
}

fn generate_socket_addr() -> SocketAddr {
Expand Down
2 changes: 1 addition & 1 deletion crates/dht/src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use librqbit_core::id20::Id20;
use librqbit_core::hash_id::Id20;
use serde::Serializer;

pub fn serialize_id20<S>(id: &Id20, ser: S) -> Result<S::Ok, S::Error>
Expand Down
2 changes: 1 addition & 1 deletion crates/librqbit/src/dht_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use tracing::debug;
use crate::{
peer_connection::PeerConnectionOptions, peer_info_reader, spawn_utils::BlockingSpawner,
};
use librqbit_core::id20::Id20;
use librqbit_core::hash_id::Id20;

#[derive(Debug)]
pub enum ReadMetainfoResult<Rx> {
Expand Down
6 changes: 3 additions & 3 deletions crates/librqbit/src/peer_connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::{
use anyhow::{bail, Context};
use buffers::{ByteBuf, ByteString};
use clone_to_owned::CloneToOwned;
use librqbit_core::{id20::Id20, lengths::ChunkInfo, peer_id::try_decode_peer_id};
use librqbit_core::{hash_id::Id20, lengths::ChunkInfo, peer_id::try_decode_peer_id};
use parking_lot::RwLock;
use peer_binary_protocol::{
extended::{handshake::ExtendedHandshake, ExtendedMessage},
Expand Down Expand Up @@ -149,7 +149,7 @@ impl<H: PeerConnectionHandler> PeerConnection<H> {

trace!(
"incoming connection: id={:?}",
try_decode_peer_id(Id20(handshake.peer_id))
try_decode_peer_id(Id20::new(handshake.peer_id))
);

let mut write_buf = Vec::<u8>::with_capacity(PIECE_MESSAGE_DEFAULT_LEN);
Expand Down Expand Up @@ -217,7 +217,7 @@ impl<H: PeerConnectionHandler> PeerConnection<H> {
.map_err(|e| anyhow::anyhow!("error deserializing handshake: {:?}", e))?;

let h_supports_extended = h.supports_extended();
trace!("connected: id={:?}", try_decode_peer_id(Id20(h.peer_id)));
trace!("connected: id={:?}", try_decode_peer_id(Id20::new(h.peer_id)));
if h.info_hash != self.info_hash.0 {
anyhow::bail!("info hash does not match");
}
Expand Down
4 changes: 2 additions & 2 deletions crates/librqbit/src/peer_info_reader/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use bencode::from_bytes;
use buffers::{ByteBuf, ByteString};
use librqbit_core::{
constants::CHUNK_SIZE,
id20::Id20,
hash_id::Id20,
lengths::{ceil_div_u64, last_element_size_u64, ChunkInfo},
torrent_metainfo::TorrentMetaV1Info,
};
Expand Down Expand Up @@ -226,7 +226,7 @@ impl PeerConnectionHandler for Handler {
mod tests {
use std::{net::SocketAddr, str::FromStr, sync::Once};

use librqbit_core::id20::Id20;
use librqbit_core::hash_id::Id20;
use librqbit_core::peer_id::generate_peer_id;

use crate::spawn_utils::BlockingSpawner;
Expand Down
10 changes: 4 additions & 6 deletions crates/librqbit/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,7 @@ impl Session {
));
}

bail!("didn't find a matching torrent for {:?}", Id20(h.info_hash))
bail!("didn't find a matching torrent for {:?}", Id20::new(h.info_hash))
}

async fn task_tcp_listener(self: Arc<Self>, l: TcpListener) -> anyhow::Result<()> {
Expand Down Expand Up @@ -757,18 +757,16 @@ impl Session {

let (info_hash, info, dht_rx, trackers, initial_peers) = match add {
AddTorrent::Url(magnet) if magnet.starts_with("magnet:") => {
let Magnet {
info_hash,
trackers,
} = Magnet::parse(&magnet).context("provided path is not a valid magnet URL")?;
let magnet = Magnet::parse(&magnet).context("provided path is not a valid magnet URL")?;
let info_hash = magnet.as_id20().context("magnet link didn't contain a BTv1 infohash")?;

let dht_rx = self
.dht
.as_ref()
.context("magnet links without DHT are not supported")?
.get_peers(info_hash, announce_port)?;

let trackers = trackers
let trackers = magnet.trackers
.into_iter()
.filter_map(|url| match reqwest::Url::parse(&url) {
Ok(url) => Some(url),
Expand Down
8 changes: 4 additions & 4 deletions crates/librqbit/src/torrent_state/live/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ use clone_to_owned::CloneToOwned;
use futures::{stream::FuturesUnordered, StreamExt};
use itertools::Itertools;
use librqbit_core::{
id20::Id20,
hash_id::Id20,
lengths::{ChunkInfo, Lengths, ValidPieceIndex},
spawn_utils::spawn_with_cancel,
speed_estimator::SpeedEstimator,
Expand Down Expand Up @@ -383,7 +383,7 @@ impl TorrentStateLive {
let peer = occ.get_mut();
peer.state
.incoming_connection(
Id20(checked_peer.handshake.peer_id),
Id20::new(checked_peer.handshake.peer_id),
tx.clone(),
&self.peers.stats,
)
Expand All @@ -393,7 +393,7 @@ impl TorrentStateLive {
Entry::Vacant(vac) => {
atomic_inc(&self.peers.stats.seen);
let peer = Peer::new_live_for_incoming_connection(
Id20(checked_peer.handshake.peer_id),
Id20::new(checked_peer.handshake.peer_id),
tx.clone(),
&self.peers.stats,
);
Expand Down Expand Up @@ -598,7 +598,7 @@ impl TorrentStateLive {
fn set_peer_live<B>(&self, handle: PeerHandle, h: Handshake<B>) {
self.peers.with_peer_mut(handle, "set_peer_live", |p| {
p.state
.connecting_to_live(Id20(h.peer_id), &self.peers.stats);
.connecting_to_live(Id20::new(h.peer_id), &self.peers.stats);
});
}

Expand Down
2 changes: 1 addition & 1 deletion crates/librqbit/src/torrent_state/live/peer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ pub mod stats;

use std::collections::HashSet;

use librqbit_core::id20::Id20;
use librqbit_core::hash_id::Id20;
use librqbit_core::lengths::{ChunkInfo, ValidPieceIndex};

use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender};
Expand Down
2 changes: 1 addition & 1 deletion crates/librqbit/src/torrent_state/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use anyhow::bail;
use anyhow::Context;
use buffers::ByteString;
use dht::RequestPeersStream;
use librqbit_core::id20::Id20;
use librqbit_core::hash_id::Id20;
use librqbit_core::lengths::Lengths;
use librqbit_core::peer_id::generate_peer_id;

Expand Down
6 changes: 3 additions & 3 deletions crates/librqbit/src/tracker_comms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::{
str::FromStr,
};

use librqbit_core::id20::Id20;
use librqbit_core::hash_id::Id20;

#[derive(Clone, Copy)]
pub enum TrackerRequestEvent {
Expand Down Expand Up @@ -207,10 +207,10 @@ mod tests {
use super::*;
#[test]
fn test_serialize() {
let info_hash = Id20([
let info_hash = Id20::new([
1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
]);
let peer_id = Id20([
let peer_id = Id20::new([
1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
]);
let request = TrackerRequest {
Expand Down
Loading
Loading