diff --git a/src/link.rs b/src/link.rs index 079c7d7..e315d05 100644 --- a/src/link.rs +++ b/src/link.rs @@ -199,6 +199,8 @@ impl Server { "SVSCMODE" if registered && self.source_is_service(msg) => self.link_svscmode(uid, msg), "ENCAP" if registered => self.link_encap(uid, msg), "METADATA" if registered => self.link_metadata(uid, msg), + "CHGHOST" if registered => self.link_chghost_recv(uid, msg), + "CHGIDENT" if registered => self.link_chgident_recv(uid, msg), "SASL" if registered => self.link_sasl(uid, msg), "BURST" => { if let Some(l) = self.links.get_mut(&uid) { @@ -801,6 +803,39 @@ impl Server { .map(|sv| sv.via) } + /// `: CHGHOST ` — a services vhost / oper host change + /// (arrives ENCAP'd to the target's server). Apply to a local target (which + /// propagates + hostcycles via `change_host_ident`), or forward toward a remote one. + fn link_chghost_recv(&mut self, from: Uid, msg: &Message) { + let (Some(target), Some(host)) = + (msg.params.first().cloned(), msg.params.get(1).cloned()) + else { + return; + }; + match self.link_local_target(&target) { + Some(tuid) => self.change_host_ident(tuid, None, Some(&host)), + None => { + self.forward_to_target(&target, msg, from); + } + } + } + + /// `: CHGIDENT ` — a services/oper ident change; the + /// `ident@host` form of a vhost arrives as a CHGIDENT then a CHGHOST. + fn link_chgident_recv(&mut self, from: Uid, msg: &Message) { + let (Some(target), Some(ident)) = + (msg.params.first().cloned(), msg.params.get(1).cloned()) + else { + return; + }; + match self.link_local_target(&target) { + Some(tuid) => self.change_host_ident(tuid, Some(&ident), None), + None => { + self.forward_to_target(&target, msg, from); + } + } + } + /// `:src METADATA :` — services sync metadata onto a /// user. We apply `accountname` (login/logout); other keys are accepted and /// ignored for now. Forwarded on if the target is remote.