configurable resolved hostname in the hostmask (use_resolved_host)

This commit is contained in:
Jean Chevronnet 2026-08-08 00:09:28 +00:00
parent 4fc26d13e9
commit dbdeb97392
5 changed files with 44 additions and 8 deletions

View file

@ -32,8 +32,12 @@ oper = admin CHANGE_THIS_PASSWORD
cloak_key = CHANGE_THIS_TO_A_LONG_RANDOM_HEX_STRING
# reverse-DNS clients on connect (the "*** Looking up your hostname..." notices).
# on (default) shows resolved hostnames; off keeps bare IPs.
# on (default) performs the lookup and reports the result; off skips it (bare IP).
resolve_hosts = on
# whether a resolved hostname is used in the hostmask (nick!user@host). on (default)
# shows the domain; off keeps the IP in the mask even though the lookup still runs
# and reports "Found your hostname". Only matters when resolve_hosts = on.
use_resolved_host = on
# antimixedutf8 — block spam that mixes look-alike scripts within words.
# action = block | kill | gline | kline | zline ; target = both | channel | private

View file

@ -70,6 +70,7 @@ pub struct Config {
pub censor: Vec<(String, String)>, // +G bad words: (find, replace); empty replace = block
pub amu: AntiMixedCfg, // antimixedutf8 module config
pub resolve_hosts: bool, // reverse-DNS clients on connect (default on)
pub use_resolved_host: bool, // put the resolved hostname in the hostmask (default on)
}
impl Default for Config {
@ -92,6 +93,7 @@ impl Default for Config {
censor: Vec::new(),
amu: AntiMixedCfg::default(),
resolve_hosts: true,
use_resolved_host: true,
}
}
}
@ -193,6 +195,12 @@ impl Config {
"off" | "false" | "no" | "0"
)
}
"use_resolved_host" | "resolved_hostmask" | "hostmask_dns" => {
c.use_resolved_host = !matches!(
v.to_ascii_lowercase().as_str(),
"off" | "false" | "no" | "0"
)
}
_ => {}
}
}

View file

@ -229,6 +229,8 @@ impl Command for Rehash {
s.cloak_key = fresh.cloak_key;
s.censor = fresh.censor;
s.amu = fresh.amu;
s.resolve_hosts = fresh.resolve_hosts;
s.use_resolved_host = fresh.use_resolved_host;
s.numeric(uid, RPL_REHASHING, &format!("{} :Rehashing", s.conf_path));
CmdResult::Ok
}

View file

@ -98,6 +98,7 @@ pub struct Server {
pub censor: Vec<(String, String)>, // +G bad words: (find, replace)
pub amu: crate::config::AntiMixedCfg, // antimixedutf8 module config
pub resolve_hosts: bool, // reverse-DNS clients on connect
pub use_resolved_host: bool, // apply the resolved name to the hostmask
pub event_tx: Sender<Event>, // self-inject events (DNS results)
}
@ -133,6 +134,7 @@ impl Server {
censor: cfg.censor,
amu: cfg.amu,
resolve_hosts: cfg.resolve_hosts,
use_resolved_host: cfg.use_resolved_host,
event_tx,
}
}
@ -252,9 +254,14 @@ impl Server {
"Couldn't look up your hostname; using your IP address instead",
),
}
let apply = self.use_resolved_host;
if let Some(u) = self.users.get_mut(&uid) {
if let Some(h) = host {
u.host = h;
// `use_resolved_host = off` keeps the IP in the hostmask even though we
// resolved and reported the name above.
if apply {
if let Some(h) = host {
u.host = h;
}
}
u.dns_pending = false;
}
@ -570,6 +577,21 @@ mod tests {
Server::new(Config::default(), tx)
}
#[test]
fn resolved_host_applied_only_when_configured() {
let mut s = srv(); // use_resolved_host = true (default)
let _a = add_user(&mut s, 1, "ann"); // host starts "localhost"
s.on_resolved(1, Some("host.example.net".to_string()));
assert_eq!(s.users[&1].host, "host.example.net");
assert!(!s.users[&1].dns_pending);
s.use_resolved_host = false; // resolve + report, but keep the IP in the mask
let _b = add_user(&mut s, 2, "bob");
s.on_resolved(2, Some("host.example.net".to_string()));
assert_eq!(s.users[&2].host, "localhost");
assert!(!s.users[&2].dns_pending); // registration still un-held either way
}
#[test]
fn join_broadcasts_and_tracks_membership() {
let mut s = srv();

View file

@ -197,12 +197,12 @@ pub struct User {
pub nick: String, // "" until NICK
pub ident: String, // "" until USER
pub realname: String,
pub host: String, // displayed host: reverse-DNS name if resolved, else IP
pub cloak: String, // masked host shown under +x ("" until computed)
pub vhost: Option<String>, // displayed-host override (CHGHOST/SETHOST vhost)
pub secure: bool, // connected over TLS (drives WHOIS 671 / sslinfo)
pub host: String, // displayed host: reverse-DNS name if resolved, else IP
pub cloak: String, // masked host shown under +x ("" until computed)
pub vhost: Option<String>, // displayed-host override (CHGHOST/SETHOST vhost)
pub secure: bool, // connected over TLS (drives WHOIS 671 / sslinfo)
pub account: Option<String>, // logged-in account name (set by services)
pub signon: u64, // unix secs at registration (WHOIS 317)
pub signon: u64, // unix secs at registration (WHOIS 317)
pub addr: SocketAddr,
pub registered: bool,
pub dns_pending: bool, // holding registration for a reverse-DNS lookup