mirror of
https://codeberg.org/slatian/service.echoip-slatecave.git
synced 2025-07-19 23:36:03 +02:00
cargo update
This commit is contained in:
@ -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;
|
||||
|
43
src/main.rs
43
src/main.rs
@ -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
23
src/nat64.rs
Normal 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
|
||||
}
|
||||
|
Reference in New Issue
Block a user