// Copyright Marcus Del Favero 2025
// Licensed under the GNU AGPLv3 with an exception, see `README.md` for details
use std::net::{SocketAddr, Ipv4Addr};

/**
 * Data structure used for rate limiting.
 *
 * A naïve solution is to keep track of the resources used for each individual
 * IP address, under the assumption that it is difficult for a malicious user to
 * obtain a large number of IP addresses.
 *
 * This assumption holds for IPv4 but not for IPv6 in which home networks are
 * usually assigned /56 or even /48 blocks, which easily allows bypassing such
 * rate limiting.
 *
 * The solution is to group together /48 blocks of IPv6 addresses when keeping
 * track of the resources used. A disadvantage with this is that a large number
 * of users could be affected for users whose ISPs assign /64 blocks to home
 * networks.
 */
#[derive(PartialEq, Eq, PartialOrd, Ord)]
pub enum IpBlock {
	V4(Ipv4Addr),
	V6(u64),
}

impl From<SocketAddr> for IpBlock {
	fn from(addr: SocketAddr) -> IpBlock {
		match addr {
			SocketAddr::V4(addr) => IpBlock::V4(*addr.ip()),
			SocketAddr::V6(addr) => IpBlock::V6((addr.ip().to_bits() >> 80) as u64),
		}
	}
}
