summaryrefslogtreecommitdiff
path: root/ext/node/ops/blocklist.rs
diff options
context:
space:
mode:
authorSatya Rohith <me@satyarohith.com>2024-07-12 14:25:17 +0530
committerGitHub <noreply@github.com>2024-07-12 14:25:17 +0530
commit8cbf81cf0840aa9c2e7c8e845748b422827c9b88 (patch)
treec74b389a7627d0d2ef7cbc7a1e4cc4f0e2d87e1e /ext/node/ops/blocklist.rs
parentfee4d3a7627634e0ac352c832d821da9127b9b97 (diff)
fix(ext/node): handle prefix mapping for IPv4-mapped IPv6 addresses (#24546)
Ensure that the prefix is properly adjusted when dealing with IPv4 addresses mapped to IPv6. This fixes inconsistencies in network range calculations for mapped addresses. Closes https://github.com/denoland/deno/issues/24525
Diffstat (limited to 'ext/node/ops/blocklist.rs')
-rw-r--r--ext/node/ops/blocklist.rs54
1 files changed, 36 insertions, 18 deletions
diff --git a/ext/node/ops/blocklist.rs b/ext/node/ops/blocklist.rs
index 182f15df3..332cdda8f 100644
--- a/ext/node/ops/blocklist.rs
+++ b/ext/node/ops/blocklist.rs
@@ -119,33 +119,44 @@ impl BlockList {
}
}
- fn map_addr_add_network(&mut self, addr: IpAddr, prefix: Option<u8>) {
+ fn map_addr_add_network(
+ &mut self,
+ addr: IpAddr,
+ prefix: Option<u8>,
+ ) -> Result<(), AnyError> {
match addr {
IpAddr::V4(addr) => {
- self.rules.insert(IpNetwork::V4(
- Ipv4Network::new(addr, prefix.unwrap_or(32)).unwrap(),
- ));
- self.rules.insert(IpNetwork::V6(
- Ipv6Network::new(addr.to_ipv6_mapped(), prefix.unwrap_or(128))
- .unwrap(),
- ));
+ let ipv4_prefix = prefix.unwrap_or(32);
+ self
+ .rules
+ .insert(IpNetwork::V4(Ipv4Network::new(addr, ipv4_prefix)?));
+
+ let ipv6_mapped = addr.to_ipv6_mapped();
+ let ipv6_prefix = 96 + ipv4_prefix; // IPv4-mapped IPv6 address prefix starts at 96
+ self
+ .rules
+ .insert(IpNetwork::V6(Ipv6Network::new(ipv6_mapped, ipv6_prefix)?));
}
IpAddr::V6(addr) => {
if let Some(ipv4_mapped) = addr.to_ipv4_mapped() {
- self.rules.insert(IpNetwork::V4(
- Ipv4Network::new(ipv4_mapped, prefix.unwrap_or(32)).unwrap(),
- ));
+ let ipv4_prefix = prefix.map(|v| v.clamp(96, 128) - 96).unwrap_or(32);
+ self
+ .rules
+ .insert(IpNetwork::V4(Ipv4Network::new(ipv4_mapped, ipv4_prefix)?));
}
- self.rules.insert(IpNetwork::V6(
- Ipv6Network::new(addr, prefix.unwrap_or(128)).unwrap(),
- ));
+
+ let ipv6_prefix = prefix.unwrap_or(128);
+ self
+ .rules
+ .insert(IpNetwork::V6(Ipv6Network::new(addr, ipv6_prefix)?));
}
};
+ Ok(())
}
pub fn add_address(&mut self, address: &str) -> Result<(), AnyError> {
let ip: IpAddr = address.parse()?;
- self.map_addr_add_network(ip, None);
+ self.map_addr_add_network(ip, None)?;
Ok(())
}
@@ -167,7 +178,7 @@ impl BlockList {
}
for ip in start_u32..=end_u32 {
let addr: Ipv4Addr = ip.into();
- self.map_addr_add_network(IpAddr::V4(addr), None);
+ self.map_addr_add_network(IpAddr::V4(addr), None)?;
}
}
(IpAddr::V6(start), IpAddr::V6(end)) => {
@@ -179,7 +190,7 @@ impl BlockList {
}
for ip in start_u128..=end_u128 {
let addr: Ipv6Addr = ip.into();
- self.map_addr_add_network(IpAddr::V6(addr), None);
+ self.map_addr_add_network(IpAddr::V6(addr), None)?;
}
}
_ => bail!("IP version mismatch between start and end addresses"),
@@ -189,7 +200,7 @@ impl BlockList {
pub fn add_subnet(&mut self, addr: &str, prefix: u8) -> Result<(), AnyError> {
let ip: IpAddr = addr.parse()?;
- self.map_addr_add_network(ip, Some(prefix));
+ self.map_addr_add_network(ip, Some(prefix))?;
Ok(())
}
@@ -255,9 +266,16 @@ mod tests {
// IPv6 subnet
let mut block_list = BlockList::new();
block_list.add_subnet("2001:db8::", 64).unwrap();
+ block_list.add_subnet("::ffff:127.0.0.1", 128).unwrap();
assert!(block_list.check("2001:db8::1", "ipv6").unwrap());
assert!(block_list.check("2001:db8::ffff", "ipv6").unwrap());
assert!(!block_list.check("192.168.0.1", "ipv4").unwrap());
+
+ // Check host addresses of IPv4 mapped IPv6 address
+ let mut block_list = BlockList::new();
+ block_list.add_subnet("1.1.1.0", 30).unwrap();
+ assert!(block_list.check("::ffff:1.1.1.1", "ipv6").unwrap());
+ assert!(!block_list.check("::ffff:1.1.1.4", "ipv6").unwrap());
}
#[test]