/ crates / tor-cell / tests / test_relaycell.rs
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  }