Skip to content
This repository was archived by the owner on Dec 10, 2022. It is now read-only.

Commit 1e41101

Browse files
authored
Merge pull request #33 from tox-rs/dht_bootstrap_info
feat(dht): add BootstrapInfo packet parsing
2 parents bca4db0 + 01c50ab commit 1e41101

File tree

1 file changed

+70
-3
lines changed

1 file changed

+70
-3
lines changed

src/toxcore/dht_new/packet.rs

Lines changed: 70 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
* takes care of the serializing and de-serializing DHT packets
2626
*/
2727

28-
use nom::{le_u8, be_u64, rest};
28+
use nom::{le_u8, be_u32, be_u64, rest};
2929

3030
use std::io::{Error, ErrorKind};
3131

@@ -78,7 +78,8 @@ pub enum DhtPacket {
7878
OnionResponse2(OnionResponse2),
7979
/// [`OnionResponse1`](../onion/struct.OnionResponse1.html) structure.
8080
OnionResponse1(OnionResponse1),
81-
// TODO: BootstrapInfo
81+
/// [`BootstrapInfo`](./struct.BootstrapInfo.html) structure.
82+
BootstrapInfo(BootstrapInfo)
8283
}
8384

8485
impl ToBytes for DhtPacket {
@@ -100,6 +101,7 @@ impl ToBytes for DhtPacket {
100101
DhtPacket::OnionResponse3(ref p) => p.to_bytes(buf),
101102
DhtPacket::OnionResponse2(ref p) => p.to_bytes(buf),
102103
DhtPacket::OnionResponse1(ref p) => p.to_bytes(buf),
104+
DhtPacket::BootstrapInfo(ref p) => p.to_bytes(buf)
103105
}
104106
}
105107
}
@@ -121,7 +123,8 @@ impl FromBytes for DhtPacket {
121123
map!(OnionDataResponse::from_bytes, DhtPacket::OnionDataResponse) |
122124
map!(OnionResponse3::from_bytes, DhtPacket::OnionResponse3) |
123125
map!(OnionResponse2::from_bytes, DhtPacket::OnionResponse2) |
124-
map!(OnionResponse1::from_bytes, DhtPacket::OnionResponse1)
126+
map!(OnionResponse1::from_bytes, DhtPacket::OnionResponse1) |
127+
map!(BootstrapInfo::from_bytes, DhtPacket::BootstrapInfo)
125128
));
126129
}
127130

@@ -804,6 +807,62 @@ impl FromBytes for LanDiscovery {
804807
));
805808
}
806809

810+
/** Sent by both client and server, only server will respond.
811+
When server receives this packet it may respond with the version of the library
812+
plus MoTD (message of the day). The max length of MoTD is 256 bytes so the max packet
813+
lenght of server BootstrapInfo is 261=(1+4+256) bytes.
814+
815+
Client must send a BootstrapInfo of exactly 78 bytes, the only 1 field is required: `packet type`
816+
which is filled automatically. So version may be filled with any value, so does MoTD, but
817+
it has to be exactly 73=(78-1-4) bytes long. The server should check that the size of the
818+
packet is exactly 78 bytes long (or MoTD=73 bytes filled with any values). Frankly speaking,
819+
there should be neither `version` nor `motd` fields in the request version, the serialized form
820+
should be 1 byte with packet type + (78-1) bytes of trash, but this implementation is simplified.
821+
822+
Serialized form:
823+
824+
Length | Contents
825+
----------- | --------
826+
`1` | `0xF0`
827+
`4` | Version in BigEndian
828+
variable | MoTD, must not longer than 256 bytes
829+
830+
*/
831+
#[derive(Clone, Debug, Eq, PartialEq)]
832+
pub struct BootstrapInfo {
833+
/// The version of DHT server
834+
pub version: u32,
835+
/// Message of the day
836+
pub motd: Vec<u8>,
837+
}
838+
839+
/// Length of in bytes of MoTD field of [`BootstrapInfo`](./struct.BootstrapInfo.html)
840+
/// when server responds with info.
841+
pub const BOOSTRAP_SERVER_MAX_MOTD_LENGTH: usize = 256;
842+
/// Length of in bytes of MoTD field of [`BootstrapInfo`](./struct.BootstrapInfo.html)
843+
/// when client requests info. 73 = 78 (max client request len) - 1 (type) - 4 (version)
844+
pub const BOOSTRAP_CLIENT_MAX_MOTD_LENGTH: usize = 73;
845+
846+
impl ToBytes for BootstrapInfo {
847+
fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> {
848+
do_gen!(buf,
849+
gen_be_u8!(0xf0) >>
850+
gen_be_u32!(self.version) >>
851+
gen_slice!(self.motd.as_slice())
852+
)
853+
}
854+
}
855+
856+
impl FromBytes for BootstrapInfo {
857+
named!(from_bytes<BootstrapInfo>, do_parse!(
858+
tag!(&[0xf0][..]) >>
859+
version: be_u32 >>
860+
motd: verify!(rest, |motd: &[u8]| motd.len() <= BOOSTRAP_SERVER_MAX_MOTD_LENGTH) >>
861+
(BootstrapInfo { version, motd: motd.to_vec() })
862+
));
863+
}
864+
865+
807866
#[cfg(test)]
808867
mod tests {
809868
use super::*;
@@ -1295,6 +1354,14 @@ mod tests {
12951354
})
12961355
);
12971356

1357+
encode_decode_test!(
1358+
bootstrap_info_encode_decode,
1359+
DhtPacket::BootstrapInfo(BootstrapInfo {
1360+
version: 42,
1361+
motd: vec![1, 2, 3, 4]
1362+
})
1363+
);
1364+
12981365
macro_rules! dht_packet_encrypt_decrypt (
12991366
($test:ident, $packet:ident, $payload:expr) => (
13001367
#[test]

0 commit comments

Comments
 (0)