-
Notifications
You must be signed in to change notification settings - Fork 53
Re-implement connection ID generation for UDP tracker #60
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
Closed
Closed
Changes from all commits
Commits
Show all changes
93 commits
Select commit
Hold shift + click to select a range
9ee34f8
test: add test for Instant serialization
josecelano 27e04e6
docs: mod udp tracker description
josecelano d8b13e5
test: added temp test for udp tracker connetion id
josecelano 6c2f312
test: fix UDP conn ID generation test by mocking current time
josecelano bfa803b
refactor: rename function
josecelano 33bc38d
test: updated connection id tests to test for BEP-15 requirements
mickvandijke 5c0551e
feat: improved get_connection_id function to conform with the require…
mickvandijke 6e1689e
test: added benchmarks to test the speed of generating a connection id
mickvandijke 2f16d13
refactor: renamed variables and removed unused import
mickvandijke 2255f22
Merge pull request #67 from WarmBeer/protocol-tests
mickvandijke a10624c
test: add test for Instant serialization
josecelano 925344a
docs: mod udp tracker description
josecelano 52390bf
test: added temp test for udp tracker connetion id
josecelano 38e65e6
test: fix UDP conn ID generation test by mocking current time
josecelano 0fa29b2
refactor: rename function
josecelano 8667652
test: updated connection id tests to test for BEP-15 requirements
mickvandijke fddaaac
feat: improved get_connection_id function to conform with the require…
mickvandijke f36e673
test: added benchmarks to test the speed of generating a connection id
mickvandijke 3880891
refactor: renamed variables and removed unused import
mickvandijke 0f2beba
test: fix test for new implementation of get_connection_id
josecelano de1e71a
Merge branch 'protocol-tests' of github.com:torrust/torrust-tracker i…
josecelano 55bb73c
test: add test for UDB connection ID verification
josecelano 0feea82
refactor: move get_connection_id to its module inside UDP module
josecelano 89d4f70
refactor: remove duplciate function
josecelano 692a92d
refactor: move Instant serializer to its own mod in tracker mod
josecelano bf639b8
refactor: rename variable
josecelano eb679a7
feat: change server secret for udp connection id
josecelano 897697d
refactor: change type and inject server secret for hashing connection id
josecelano f2d7d5f
refactor: wip. extract logic to generate time bound pepper
josecelano 4769a49
refactor: extract struct ByteArray32
josecelano 5b42af2
refactor: move time bound pepper to a new mod
josecelano a444bce
refactor: rename tests
josecelano a8322ed
refactor: extract struct TimeBoundPepper
josecelano e3b7b6e
refactor: create alias type Timestamp
josecelano 55982fe
feat: implemented @da2ce7's proposal for TimeBoundPepper
josecelano 1ba7c39
refactor: extract ByteArray32 constructors
josecelano 3287448
docs: add comments
josecelano 842487c
docs: fix typo
josecelano e6afa46
test: ByteArray32 converter from socker port (u16)
josecelano a2d1849
docs: add description for connection_id mod
josecelano c7637a8
docs: add properties for connection id
da2ce7 2b2ec2b
refactor: WIP. Encrypted connection id
josecelano 13cf81e
refactor: add rust-crypto dependency for blowfish cypher
josecelano e6a205b
refactor: add encryption to connection id
josecelano a33db6d
refactor: extract functions
josecelano 88ca2f4
refactor: rename varaiblbe
josecelano 1b651d5
refactor: extract function
josecelano 430c5dd
refactor:extract functions
josecelano e065f46
refactor: removed unused test
josecelano d6e428f
refactor: extract mod for Timestamp
josecelano 2f92919
refactor: remove unused mod time_bound_pepper
josecelano c4115b1
refactor: create mod for connection id
josecelano 5f613a6
refactor: store expiration time in connection id
josecelano ec0915d
docs: remove false test from test execution output
josecelano 9511174
refactor: extract struct ClientId
josecelano f9a136d
test: add test for encryption
josecelano 94c2bd4
fix: check client id in connection id verification
josecelano 169228f
refactor: remove unused code
josecelano 90a033d
refactor: move functions
josecelano cdf5cc6
refactor: extract struct Timestamp32
josecelano 68b65b5
refactor: remove comment
josecelano 09fa7cc
refactor: rename struct
josecelano 0efd858
refactor: Timestamp32. Use trait for convertion
josecelano 0fee0b5
feat: new CYpher trait and Blowfish impl
josecelano 14e6e5e
refactor: extract struct Cypher
josecelano f46ce2f
refactor: rename function
josecelano 02a1460
refactor: extract connection ID issuer
josecelano 35819b4
refactor: extract struct ConnectionIdData
josecelano 8eaefb1
refactor: extract struct EncryptedConnectionIdData
josecelano 65c1b3b
fix: remove unneeded unwrap
josecelano dcf6d82
refactor: extract guard clauses for connection id verification
josecelano cd32b86
refactor: extract methods for EncryptedConnectionIdIssuer
josecelano 4f01881
refactor: rename methods
josecelano b659d01
refactor: ClientId. Extract trait for hasher
josecelano 1b98b15
refactor: remove unused hasher implemention for client id
josecelano 460d62a
feat: verify connection id in announce and scrape requests
josecelano 55c040d
refactor: simplify trait ConnectionIdIssuer
josecelano c891e83
feat: do not send response when connection id is not valid
josecelano 75a2e5a
refactor: rename mod handlers to packet_handler
josecelano a2b38d4
refactor: extract mod request_handler
josecelano 5801e5f
refactor: extract UDP RequestHandler
josecelano c3c31e5
refactor: moved RequestHandler creation to UdpServer::start()
mickvandijke f125781
refactor: renamed RequestHandler to PacketHandler
mickvandijke 36e34ec
Merge pull request #78 from torrust/mick/protocol-tests
josecelano f70c11c
feat: generate a random encryption key
josecelano 6c6c33d
refactor: use a tuple struct for Timestamp32
josecelano e793731
refactor: move method
josecelano 90af290
refactor: extract EncodedConnectionIdData
josecelano 84ae58c
refactor: rename methods
josecelano ce45c57
refactor: fix clippy warnings in upd::connection
josecelano 9ad1ed7
refactor: inject clock into PackerHandler
josecelano 0d45e20
refactor: rename PacketHandler attribtues
josecelano ab6a99f
refactor: replace deprecated crate for Blowfish cypher
josecelano File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4}; | ||
| use aquatic_udp_protocol::ConnectionId; | ||
| use criterion::{Criterion, criterion_group, criterion_main}; | ||
| use torrust_tracker::{udp::connection_id::get_connection_id, protocol::clock::current_timestamp}; | ||
|
|
||
| fn get_connection_id_old(current_time: u64, port: u16) -> ConnectionId { | ||
| let time_i64 = (current_time / 3600) as i64; | ||
|
|
||
| ConnectionId((time_i64 | port as i64) << 36) | ||
| } | ||
|
|
||
| pub fn benchmark_generate_id_with_time_and_port(bench: &mut Criterion) { | ||
| let remote_address = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 117); | ||
| let current_time = current_timestamp(); | ||
|
|
||
| bench.bench_function("generate_id_with_time_and_port", |b| { | ||
| b.iter(|| { | ||
| // Inner closure, the actual test | ||
| let _ = get_connection_id_old(current_time, remote_address.port()); | ||
| }) | ||
| }); | ||
| } | ||
|
|
||
| pub fn benchmark_generate_id_with_hashed_time_and_ip_and_port_and_salt(bench: &mut Criterion) { | ||
| let remote_address = SocketAddr::from(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 117)); | ||
| let current_time = current_timestamp(); | ||
| let server_secret = [0;32]; | ||
|
|
||
| bench.bench_function("generate_id_with_hashed_time_and_ip_and_port_and_salt", |b| { | ||
| b.iter(|| { | ||
| // Inner closure, the actual test | ||
| let _ = get_connection_id(&server_secret, &remote_address, current_time); | ||
| }) | ||
| }); | ||
| } | ||
|
|
||
| criterion_group!(benches, benchmark_generate_id_with_time_and_port, benchmark_generate_id_with_hashed_time_and_ip_and_port_and_salt); | ||
| criterion_main!(benches); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| use std::time::SystemTime; | ||
|
|
||
| pub type UnixTime = u64; | ||
|
|
||
| /// A Clock which uses the UNIX time. | ||
| pub trait UnixClock { | ||
| fn now(&self) -> UnixTime; | ||
| } | ||
|
|
||
| /// A Clock which uses the operating system to determine the time. | ||
| pub struct SystemUnixClock; | ||
|
|
||
| impl UnixClock for SystemUnixClock { | ||
| fn now(&self) -> UnixTime { | ||
| SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs() | ||
| } | ||
| } | ||
|
|
||
| /// It returns the current timestamp using the system clock. | ||
| pub fn current_timestamp() -> UnixTime { | ||
| SystemUnixClock.now() | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,2 @@ | ||
| pub mod common; | ||
| pub mod utils; | ||
| pub mod clock; |
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,7 @@ | ||
| pub mod tracker; | ||
| pub mod statistics; | ||
| pub mod peer; | ||
| pub mod serializer; | ||
| pub mod torrent; | ||
| pub mod key; | ||
| pub mod mode; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| /// Serializer for `std::time::Instant` type. | ||
| /// Before serializing, it converts the instant to time elapse since that instant in milliseconds. | ||
| /// | ||
| /// You can use it like this: | ||
| /// | ||
| /// ```text | ||
| /// #[serde(serialize_with = "ser_instant")] | ||
| /// pub updated: std::time::Instant, | ||
| /// ``` | ||
| /// | ||
| pub fn ser_instant<S: serde::Serializer>(inst: &std::time::Instant, ser: S) -> Result<S::Ok, S::Error> { | ||
| ser.serialize_u64(inst.elapsed().as_millis() as u64) | ||
| } | ||
|
|
||
| #[cfg(test)] | ||
| mod tests { | ||
| use std::{time::Instant}; | ||
| use serde::Serialize; | ||
|
|
||
| #[warn(unused_imports)] | ||
| use super::ser_instant; | ||
|
|
||
| #[derive(PartialEq, Eq, Debug, Clone, Serialize)] | ||
| struct S { | ||
| #[serde(serialize_with = "ser_instant")] | ||
| pub time: Instant, | ||
| } | ||
|
|
||
| #[test] | ||
| fn instant_types_can_be_serialized_as_elapsed_time_since_that_instant_in_milliseconds() { | ||
|
|
||
| use std::{thread, time}; | ||
|
|
||
| let t1 = Instant::now(); | ||
|
|
||
| let s = S { time: t1 }; | ||
|
|
||
| // Sleep 10 milliseconds | ||
| let ten_millis = time::Duration::from_millis(10); | ||
| thread::sleep(ten_millis); | ||
|
|
||
| let json_serialized_value = serde_json::to_string(&s).unwrap(); | ||
|
|
||
| // Json contains time duration since t1 instant in milliseconds | ||
| assert_eq!(json_serialized_value, r#"{"time":10}"#); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
| //! ClientId is a unique ID for the UDP tracker client. | ||
| //! Currently implemented with a hash of the socket, i.e the IP and port. | ||
| use std::hash::Hash; | ||
| use std::hash::Hasher; | ||
| use std::net::SocketAddr; | ||
|
|
||
| #[derive(PartialEq, Debug, Clone)] | ||
| pub struct ClientId { | ||
| value: [u8; 4], | ||
| } | ||
|
|
||
| pub trait Make<T: Default + Hasher> { | ||
| fn new(socket: &SocketAddr) -> Self; | ||
|
|
||
| fn hash(socket: &SocketAddr) -> [u8;8] { | ||
| let mut hasher = T::default(); | ||
| socket.hash(&mut hasher); | ||
|
|
||
| hasher.finish().to_le_bytes() | ||
| } | ||
| } | ||
|
|
||
| impl<T: Default + Hasher> Make<T> for ClientId { | ||
| fn new(socket: &SocketAddr) -> Self { | ||
| let hash = <ClientId as Make<T>>::hash(socket); | ||
|
|
||
| let mut truncated_hash: [u8; 4] = [0u8; 4]; | ||
| truncated_hash.copy_from_slice(&hash[..4]); | ||
|
|
||
| ClientId { | ||
| value: truncated_hash, | ||
| } | ||
| } | ||
| } | ||
|
|
||
| impl ClientId { | ||
| /// It generates the ID with a previously generated value | ||
| pub fn from_bytes(bytes: &[u8]) -> Self { | ||
| let mut client_id = ClientId { | ||
| value: [0u8; 4] | ||
| }; | ||
| client_id.value.copy_from_slice(bytes); | ||
| client_id | ||
| } | ||
|
|
||
| pub fn to_bytes(&self) -> [u8; 4] { | ||
| let bytes: [u8; 4] = self.value; | ||
| bytes | ||
| } | ||
| } | ||
|
|
||
| #[cfg(test)] | ||
| mod tests { | ||
| use std::{net::{IpAddr, Ipv4Addr, SocketAddr}, collections::hash_map::DefaultHasher}; | ||
|
|
||
| use super::{ClientId, Make}; | ||
|
|
||
| #[test] | ||
| fn it_should_be_a_hash_of_the_socket() { | ||
| let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080); | ||
| let id: ClientId = Make::<DefaultHasher>::new(&socket); | ||
|
|
||
| assert_eq!(id.value, [213, 195, 130, 185]); | ||
| } | ||
|
|
||
| #[test] | ||
| fn id_should_be_converted_to_a_byte_array() { | ||
| let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080); | ||
| let id: ClientId = Make::<DefaultHasher>::new(&socket); | ||
|
|
||
| assert_eq!(id.to_bytes(), [213, 195, 130, 185]); | ||
| } | ||
|
|
||
| #[test] | ||
| fn id_should_be_instantiate_from_a_previously_generated_value() { | ||
| let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080); | ||
| let id: ClientId = Make::<DefaultHasher>::new(&socket); | ||
| let bytes = id.to_bytes(); | ||
|
|
||
| assert_eq!(ClientId::from_bytes(&bytes), id); | ||
| } | ||
|
|
||
| #[test] | ||
| fn it_should_be_unique_with_different_socket_ips() { | ||
| let socket_1 = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080); | ||
| let socket_2 = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 2)), 8080); | ||
|
|
||
| assert_ne!( | ||
| <ClientId as Make::<DefaultHasher>>::new(&socket_1), | ||
| <ClientId as Make::<DefaultHasher>>::new(&socket_2) | ||
| ); | ||
| } | ||
|
|
||
| #[test] | ||
| fn it_should_be_unique_with_different_socket_ports() { | ||
| let socket_1 = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080); | ||
| let socket_2 = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8081); | ||
|
|
||
| assert_ne!( | ||
| <ClientId as Make::<DefaultHasher>>::new(&socket_1), | ||
| <ClientId as Make::<DefaultHasher>>::new(&socket_2) | ||
| ); | ||
| } | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Returning
&[u8; 4]or even&[u8]is preferred over[u8; 4], because borrowing is cheaper than creating a new owned array. Unless we want to consumeself. In that case it should be:The ClientId will then be dropped, because
valueis moved.