test_relaycell.rs
1 // Tests for encoding/decoding relay messages into relay cell bodies. 2 #![allow(clippy::uninlined_format_args)] 3 4 use tor_bytes::Error; 5 use tor_cell::relaycell::{ 6 msg::{self, AnyRelayMsg}, 7 AnyRelayMsgOuter, RelayCellFormat, RelayCmd, RelayMsg, StreamId, UnparsedRelayMsg, 8 }; 9 10 #[cfg(feature = "experimental-udp")] 11 use std::{ 12 net::{Ipv4Addr, Ipv6Addr}, 13 str::FromStr, 14 }; 15 #[cfg(feature = "experimental-udp")] 16 use tor_cell::relaycell::udp::Address; 17 18 const CELL_BODY_LEN: usize = 509; 19 20 struct BadRng; 21 impl rand::RngCore for BadRng { 22 fn next_u32(&mut self) -> u32 { 23 0xf0f0f0f0 24 } 25 fn next_u64(&mut self) -> u64 { 26 0xf0f0f0f0f0f0f0f0 27 } 28 fn fill_bytes(&mut self, dest: &mut [u8]) { 29 dest.fill(0xf0); 30 } 31 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand::Error> { 32 self.fill_bytes(dest); 33 Ok(()) 34 } 35 } 36 37 // I won't tell if you don't. 38 impl rand::CryptoRng for BadRng {} 39 40 fn decode(body: &str) -> Box<[u8; CELL_BODY_LEN]> { 41 let mut body = body.to_string(); 42 body.retain(|c| !c.is_whitespace()); 43 let mut body = hex::decode(body).unwrap(); 44 body.resize(CELL_BODY_LEN, 0xf0); // see BadRng 45 46 let mut result = [0; CELL_BODY_LEN]; 47 result.copy_from_slice(&body[..]); 48 Box::new(result) 49 } 50 51 fn cell(body: &str, id: Option<StreamId>, msg: AnyRelayMsg) { 52 let body = decode(body); 53 let mut bad_rng = BadRng; 54 55 let expected = AnyRelayMsgOuter::new(id, msg); 56 57 let decoded = AnyRelayMsgOuter::decode_singleton(RelayCellFormat::V0, body.clone()).unwrap(); 58 59 let decoded_from_partial = UnparsedRelayMsg::from_singleton_body(RelayCellFormat::V0, body) 60 .unwrap() 61 .decode::<AnyRelayMsg>() 62 .unwrap(); 63 assert_eq!(decoded_from_partial.stream_id(), decoded.stream_id()); 64 assert_eq!(decoded_from_partial.cmd(), decoded.cmd()); 65 66 assert_eq!(format!("{:?}", expected), format!("{:?}", decoded)); 67 assert_eq!( 68 format!("{:?}", expected), 69 format!("{:?}", decoded_from_partial) 70 ); 71 72 let encoded1 = decoded.encode(&mut bad_rng).unwrap(); 73 let encoded2 = expected.encode(&mut bad_rng).unwrap(); 74 75 assert_eq!(&encoded1[..], &encoded2[..]); 76 } 77 78 #[test] 79 fn bad_rng() { 80 use rand::RngCore; 81 let mut rng = BadRng; 82 83 assert_eq!(rng.next_u32(), 0xf0f0f0f0); 84 assert_eq!(rng.next_u64(), 0xf0f0f0f0f0f0f0f0); 85 let mut buf = [0u8; 19]; 86 assert!(rng.try_fill_bytes(&mut buf).is_ok()); 87 assert_eq!( 88 &buf, 89 &[ 90 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 91 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 92 ] 93 ); 94 } 95 96 #[test] 97 fn test_cells() { 98 cell( 99 "02 0000 9999 12345678 000c 6e6565642d746f2d6b6e6f77 00000000", 100 StreamId::new(0x9999), 101 msg::Data::new(&b"need-to-know"[..]).unwrap().into(), 102 ); 103 104 // length too big: 0x1f3 is one byte too many. 105 let m = decode("02 0000 9999 12345678 01f3 6e6565642d746f2d6b6e6f77 00000000"); 106 assert_eq!( 107 AnyRelayMsgOuter::decode_singleton(RelayCellFormat::V0, m).err(), 108 Some(Error::InvalidMessage( 109 "Insufficient data in relay cell".into() 110 )) 111 ); 112 113 // check accessors. 114 let m = decode("02 0000 9999 12345678 01f2 6e6565642d746f2d6b6e6f77 00000000"); 115 let c = AnyRelayMsgOuter::decode_singleton(RelayCellFormat::V0, m).unwrap(); 116 assert_eq!(c.cmd(), RelayCmd::from(2)); 117 assert_eq!(c.msg().cmd(), RelayCmd::from(2)); 118 let (s, _) = c.into_streamid_and_msg(); 119 assert_eq!(s, StreamId::new(0x9999)); 120 } 121 122 #[test] 123 fn test_streamid() { 124 let zero: Option<StreamId> = StreamId::new(0); 125 let two: Option<StreamId> = StreamId::new(2); 126 127 assert!(zero.is_none()); 128 assert!(two.is_some()); 129 130 assert_eq!(format!("{}", two.unwrap()), "2"); 131 132 assert_eq!(StreamId::get_or_zero(zero), 0_u16); 133 assert_eq!(StreamId::get_or_zero(two), 2_u16); 134 135 assert!(RelayCmd::DATA.accepts_streamid_val(two)); 136 assert!(!RelayCmd::DATA.accepts_streamid_val(zero)); 137 138 assert!(RelayCmd::EXTEND2.accepts_streamid_val(zero)); 139 assert!(!RelayCmd::EXTEND2.accepts_streamid_val(two)); 140 } 141 142 #[cfg(feature = "experimental-udp")] 143 #[test] 144 fn test_address() { 145 // IPv4 146 let ipv4 = Ipv4Addr::from_str("1.2.3.4").expect("Unable to parse IPv4"); 147 let addr = Address::from_str("1.2.3.4").expect("Unable to parse Address"); 148 assert!(matches!(addr, Address::Ipv4(_))); 149 assert_eq!(addr, Address::Ipv4(ipv4)); 150 151 // Wrong IPv4 should result in a hostname. 152 let addr = Address::from_str("1.2.3.372").expect("Unable to parse Address"); 153 assert!(addr.is_hostname()); 154 155 // Common bad IPv4 patterns 156 let addr = Address::from_str("0x23.42.42.42").expect("Unable to parse Address"); 157 assert!(addr.is_hostname()); 158 let addr = Address::from_str("0x7f000001").expect("Unable to parse Address"); 159 assert!(addr.is_hostname()); 160 let addr = Address::from_str("10.0.23").expect("Unable to parse Address"); 161 assert!(addr.is_hostname()); 162 let addr = Address::from_str("2e3:4::10.0.23").expect("Unable to parse Address"); 163 assert!(addr.is_hostname()); 164 165 // IPv6 166 let ipv6 = Ipv6Addr::from_str("4242::9").expect("Unable to parse IPv6"); 167 let addr = Address::from_str("4242::9").expect("Unable to parse Address"); 168 assert!(matches!(addr, Address::Ipv6(_))); 169 assert_eq!(addr, Address::Ipv6(ipv6)); 170 171 // Wrong IPv6 should result in a hostname. 172 let addr = Address::from_str("4242::9::5").expect("Unable to parse Address"); 173 assert!(addr.is_hostname()); 174 175 // Hostname 176 let hostname = "www.torproject.org"; 177 let addr = Address::from_str(hostname).expect("Unable to parse Address"); 178 assert!(addr.is_hostname()); 179 assert_eq!(addr, Address::Hostname(hostname.to_string().into_bytes())); 180 181 // Empty hostname 182 let hostname = ""; 183 let addr = Address::from_str(hostname).expect("Unable to parse Address"); 184 assert!(addr.is_hostname()); 185 assert_eq!(addr, Address::Hostname(hostname.to_string().into_bytes())); 186 187 // Too long hostname. 188 let hostname = "a".repeat(256); 189 let addr = Address::from_str(hostname.as_str()); 190 assert!(addr.is_err()); 191 assert_eq!( 192 addr.err(), 193 Some(Error::InvalidMessage("Hostname too long".into())) 194 ); 195 196 // Some Unicode emojis (go Gen-Z!). 197 let hostname = "👍️👍️👍️"; 198 let addr = Address::from_str(hostname).expect("Unable to parse Address"); 199 assert!(addr.is_hostname()); 200 assert_eq!(addr, Address::Hostname(hostname.to_string().into_bytes())); 201 202 // Address with nul byte. Not allowed. 203 let hostname = "aaa\0aaa"; 204 let addr = Address::from_str(hostname); 205 assert!(addr.is_err()); 206 assert_eq!( 207 addr.err(), 208 Some(Error::InvalidMessage("Nul byte not permitted".into())) 209 ); 210 }