s2s: route and apply KILL across the link (inbound handler + remote-target routing)
This commit is contained in:
parent
579c321670
commit
98fb848b8c
2 changed files with 46 additions and 0 deletions
|
|
@ -179,6 +179,16 @@ impl Command for Kill {
|
||||||
.cloned()
|
.cloned()
|
||||||
.unwrap_or_else(|| "Killed".to_string());
|
.unwrap_or_else(|| "Killed".to_string());
|
||||||
let Some(tuid) = s.find_nick(target) else {
|
let Some(tuid) = s.find_nick(target) else {
|
||||||
|
// remote target: route the KILL toward the server that owns it
|
||||||
|
if let Some((uuid, _)) = s.find_remote(target) {
|
||||||
|
let (killer_uuid, killer) = s
|
||||||
|
.users
|
||||||
|
.get(&uid)
|
||||||
|
.map(|u| (u.uuid.clone(), u.nick.clone()))
|
||||||
|
.unwrap_or_default();
|
||||||
|
s.route_kill(&killer_uuid, &uuid, &format!("{killer} ({reason})"));
|
||||||
|
return CmdResult::Ok;
|
||||||
|
}
|
||||||
s.numeric(
|
s.numeric(
|
||||||
uid,
|
uid,
|
||||||
ERR_NOSUCHNICK,
|
ERR_NOSUCHNICK,
|
||||||
|
|
|
||||||
36
src/link.rs
36
src/link.rs
|
|
@ -166,6 +166,7 @@ impl Server {
|
||||||
"UID" if registered => self.link_uid_recv(uid, msg),
|
"UID" if registered => self.link_uid_recv(uid, msg),
|
||||||
"NICK" if registered => self.link_nick_recv(uid, msg),
|
"NICK" if registered => self.link_nick_recv(uid, msg),
|
||||||
"QUIT" if registered => self.link_quit_recv(uid, msg),
|
"QUIT" if registered => self.link_quit_recv(uid, msg),
|
||||||
|
"KILL" if registered => self.link_kill_recv(uid, msg),
|
||||||
"PRIVMSG" if registered => self.link_message_recv(uid, msg, false),
|
"PRIVMSG" if registered => self.link_message_recv(uid, msg, false),
|
||||||
"NOTICE" if registered => self.link_message_recv(uid, msg, true),
|
"NOTICE" if registered => self.link_message_recv(uid, msg, true),
|
||||||
"JOIN" if registered => self.link_join_recv(uid, msg),
|
"JOIN" if registered => self.link_join_recv(uid, msg),
|
||||||
|
|
@ -1033,6 +1034,41 @@ impl Server {
|
||||||
self.propagate(&format!(":{uuid} QUIT :{reason}"), Some(via));
|
self.propagate(&format!(":{uuid} QUIT :{reason}"), Some(via));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// `:<src> KILL <target> :<reason>` — a services/oper kill from a peer. A local
|
||||||
|
/// target is notified and removed (its QUIT tells the rest of the tree); a
|
||||||
|
/// remote target is routed one hop onward.
|
||||||
|
fn link_kill_recv(&mut self, via: Uid, msg: &Message) {
|
||||||
|
let Some(src) = msg.source.clone() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let (Some(target), Some(reason)) =
|
||||||
|
(msg.params.first().cloned(), msg.params.get(1).cloned())
|
||||||
|
else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
match self.link_local_target(&target) {
|
||||||
|
Some(tuid) => {
|
||||||
|
let from = self
|
||||||
|
.uuid_prefix(&src)
|
||||||
|
.or_else(|| self.servers.get(&src).map(|sv| sv.name.clone()))
|
||||||
|
.unwrap_or_else(|| src.clone());
|
||||||
|
let nick = self.users.get(&tuid).map(|u| u.nick.clone()).unwrap_or_default();
|
||||||
|
self.send(tuid, format!(":{from} KILL {nick} :{reason}"));
|
||||||
|
self.remove_user(tuid, &format!("Killed ({reason})"));
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
self.forward_to_target(&target, msg, via);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Route a KILL toward the server that owns a remote `target` uuid.
|
||||||
|
pub fn route_kill(&self, killer: &str, target: &str, reason: &str) {
|
||||||
|
if let Some(v) = self.link_toward(target) {
|
||||||
|
self.link_out(v, format!(":{killer} KILL {target} :{reason}"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn link_message_recv(&mut self, via: Uid, msg: &Message, notice: bool) {
|
fn link_message_recv(&mut self, via: Uid, msg: &Message, notice: bool) {
|
||||||
// :<srcuuid> PRIVMSG <#chan|dstuuid> :<text>
|
// :<srcuuid> PRIVMSG <#chan|dstuuid> :<text>
|
||||||
let cmd = if notice { "NOTICE" } else { "PRIVMSG" };
|
let cmd = if notice { "NOTICE" } else { "PRIVMSG" };
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue