cargo update

This commit is contained in:
Slatian
2025-03-20 00:04:34 +01:00
parent 38be0c05d0
commit d5c5d30d32
6 changed files with 259 additions and 173 deletions

View File

@ -28,6 +28,7 @@ pub enum AddressScope {
Loopback,
Reserved,
Documentation,
Nat64,
#[default]
Unknown,
}
@ -78,6 +79,9 @@ impl AddressInfo {
// Test for the documentation address 2001:db8::/32
} else if segments[0]==0x2001 && segments[1]==0x0db8 && segments[2]==0 && segments[3]==0 {
address_scope = AddressScope::Documentation;
// Test for NAT64 address 64:ff9b::/96
} else if segments[0]==0x64 && segments[1]==0xff9b {
address_scope = AddressScope::Nat64;
// Test for multicase scope
} else if addr.is_multicast() {
address_cast = AddressCast::Multicast;

View File

@ -25,6 +25,7 @@ use env_logger::Env;
use hickory_resolver::{name_server::TokioConnectionProvider, system_conf::read_system_conf, Name, ResolveError, Resolver};
use hickory_resolver::TokioResolver;
use log::{info,warn,error};
use nat64::resolve_nat64_address;
use regex::Regex;
use serde::{Deserialize,Serialize};
use tower_http::services::ServeDir;
@ -50,6 +51,7 @@ mod config;
mod geoip;
mod idna;
mod ipinfo;
mod nat64;
mod ratelimit;
mod settings;
mod simple_dns;
@ -82,8 +84,28 @@ pub struct SearchQuery {
query: Option<String>,
}
/// Enumerates possible mapping strategies
#[derive(Deserialize, Serialize, Clone)]
#[serde(rename_all="snake_case")]
pub enum IpMappingStrategy {
/// See: https://en.wikipedia.org/wiki/NAT64
Nat64,
}
#[derive(Serialize, Clone)]
pub struct IpMapping {
strategy: IpMappingStrategy,
from_address: IpAddr,
to_address: IpAddr,
}
#[derive(Serialize, Clone)]
pub struct IpResult {
/// When the mapping is set the queried for address
/// was automtically replaced with the mapped to address.
mapping: Option<IpMapping>,
/// The address that was queried for or the mapping resulted in.
address: IpAddr,
hostname: Option<String>,
asn: Option<AsnResult>,
@ -597,6 +619,19 @@ async fn handle_ip_request(
)
}
fn get_ip_mapping(address: &IpAddr) -> Option<IpMapping> {
if let IpAddr::V6(v6_address) = address {
if let Some(nat64_result) = resolve_nat64_address(*v6_address) {
return Some(IpMapping {
from_address: *address,
to_address: IpAddr::V4(nat64_result),
strategy: IpMappingStrategy::Nat64,
});
}
}
return None;
}
async fn get_ip_result(
address: &IpAddr,
lang: &str,
@ -606,10 +641,14 @@ async fn get_ip_result(
state: &ServiceSharedState,
) -> IpResult {
let mapping = get_ip_mapping(address);
let original_address = address;
let address = &mapping.clone().map_or(*original_address, |m| m.to_address);
let mut reverse_dns_disabled_for_privacy = false;
if state.config.dns.allow_reverse_lookup &&
address == client_ip &&
(address == client_ip || original_address == client_ip) &&
dns_disable_self_lookup
{
reverse_dns_disabled_for_privacy = true;
@ -622,6 +661,7 @@ async fn get_ip_result(
// The address falls into a private range and lookup of private addresses is not allowed.
if (!state.config.server.allow_private_ip_lookup) && (ip_info.scope == AddressScope::Private || ip_info.scope == AddressScope::LinkLocal) {
return IpResult {
mapping: mapping,
address: *address,
hostname: None,
asn: None,
@ -660,6 +700,7 @@ async fn get_ip_result(
}
IpResult{
mapping: mapping,
address: *address,
hostname: hostname,
asn: asn_result,

23
src/nat64.rs Normal file
View File

@ -0,0 +1,23 @@
use std::net::Ipv4Addr;
use std::net::Ipv6Addr;
/// Resolves a NAT64 address if it is in the range of 64:ff9b::/96
pub fn resolve_nat64_address(from: Ipv6Addr) -> Option<Ipv4Addr> {
if is_nat64_address(&from) {
let segments = from.segments();
return Some(Ipv4Addr::new(
((segments[6] & 0xff00) >> 8) as u8,
(segments[6] & 0x00ff) as u8,
((segments[7] & 0xff00) >> 8) as u8,
(segments[7] & 0x00ff) as u8,
));
} else {
return None;
}
}
pub fn is_nat64_address(address: &Ipv6Addr) -> bool {
let segments = address.segments();
segments[0]==0x64 && segments[1]==0xff9b
}