Browse Source

Add conn_req_msg & ann_req_msg contructors, torrent.size() & .info_hash()

master
arnaucube 4 years ago
parent
commit
612b3b5e10
2 changed files with 60 additions and 1 deletions
  1. +3
    -0
      Cargo.toml
  2. +57
    -1
      src/lib.rs

+ 3
- 0
Cargo.toml

@ -10,3 +10,6 @@ serde_bencode = "^0.2.1"
serde = "^1.0.0"
serde_derive = "^1.0.0"
serde_bytes = "0.10.0"
byteorder = "1.3.4"
rand = "0.7"
sha-1 = "0.9.0"

+ 57
- 1
src/lib.rs

@ -1,3 +1,7 @@
use byteorder::{BigEndian, ByteOrder};
use rand::Rng;
use sha1::{Digest, Sha1};
extern crate serde;
extern crate serde_bencode;
#[macro_use]
@ -68,6 +72,55 @@ impl Torrent {
let b = std::fs::read(path).unwrap();
de::from_bytes::<Torrent>(&b).unwrap()
}
pub fn size(&self) -> u64 {
let files = self.info.files.as_ref().unwrap();
let mut size: u64 = 0;
for i in 0..files.len() {
size = size + files[i].length as u64;
}
size
}
pub fn info_hash(&self) -> Vec<u8> {
let info_bytes: Vec<u8> = ser::to_bytes(&self.info).unwrap();
let mut hasher = Sha1::new();
hasher.update(info_bytes);
let result = hasher.finalize();
result.to_vec()
}
}
const CONNECT_MSG: u32 = 0;
const ANNOUNCE_MSG: u32 = 1;
fn conn_req_msg() -> [u8; 16] {
let mut b: [u8; 16] = [0; 16];
BigEndian::write_u64(&mut b[0..8], 0x41727101980); // connection_id
let random_bytes = rand::thread_rng().gen::<[u8; 4]>();
b[12..16].clone_from_slice(&random_bytes[..]);
b
}
fn ann_req_msg(connection_id: u64, torrent: &Torrent, port: u16) -> Vec<u8> {
let mut b: [u8; 98] = [0; 98];
BigEndian::write_u64(&mut b[0..8], connection_id);
BigEndian::write_u32(&mut b[8..12], CONNECT_MSG); // action
let random_bytes = rand::thread_rng().gen::<[u8; 4]>();
b[12..16].clone_from_slice(&random_bytes[..]);
// println!("md5sum {:?}", torrent);
b[16..36].clone_from_slice(&torrent.info_hash()[..]);
println!("info_hash: {:?}", &b[16..36]);
// TODO [36..56] peerId b[36..56].clone_from_slice("todo".as_bytes());
// TODO [56..64] downloaded
println!("torrent.size(): {:?}", torrent.size());
BigEndian::write_u64(&mut b[64..72], torrent.size()); // [64..72] left
// TODO [72..80] uploaded
// TODO [80..84] event (0:none, 1:completed, 2:started, 3:stopped)
// TODO [84..88] ip address
let random_bytes = rand::thread_rng().gen::<[u8; 4]>();
b[88..92].clone_from_slice(&random_bytes[..]); // [88..92] key (random)
BigEndian::write_i32(&mut b[92..96], -1); // [92..96] num_want (default: -1)
BigEndian::write_u16(&mut b[96..98], port); // [96..98] port
b.to_vec()
}
#[cfg(test)]
@ -77,6 +130,9 @@ mod tests {
#[test]
fn test_read() {
let t = Torrent::open("test.torrent");
println!("{:?}", t);
println!("torrent: {:?}", t.info.name);
println!("announce: {:?}", t.announce.clone().unwrap());
println!("conn_req_msg: {:?}", conn_req_msg());
}
}

Loading…
Cancel
Save