1use crate::glob::GlobSet;
2use arcstr::ArcStr;
3use bytes::{Buf, BufMut, Bytes};
4use netidx_core::{
5 pack::{
6 len_wrapped_decode, len_wrapped_encode, len_wrapped_len, Pack, PackError, Z64,
7 },
8 path::Path,
9};
10use netidx_derive::Pack;
11use poolshark::Pooled;
12use smallvec::SmallVec;
13use std::{
14 cmp::{Eq, PartialEq},
15 hash::{Hash, Hasher},
16 net::SocketAddr,
17 result,
18};
19
20type Error = PackError;
21pub type Result<T> = result::Result<T, Error>;
22
23#[derive(Clone, Debug, Copy, PartialEq, Eq, Pack)]
24pub enum HashMethod {
25 Sha3_512,
26}
27
28#[derive(Clone, Debug, Copy, PartialEq, Pack)]
29pub struct AuthChallenge {
30 pub hash_method: HashMethod,
31 pub challenge: u128,
32}
33
34#[derive(Clone, Debug, PartialEq, Eq, Pack)]
35pub enum AuthRead {
36 Anonymous,
37 Krb5,
38 Local,
39 Tls,
40}
41
42#[derive(Clone, Debug, PartialEq, Eq, Pack)]
43pub enum AuthWrite {
44 Anonymous,
45 Reuse,
46 Krb5 { spn: ArcStr },
47 Local,
48 Tls { name: ArcStr },
49}
50
51#[derive(Clone, Debug, PartialEq, Eq, Pack)]
52pub struct ClientHelloWrite {
53 pub write_addr: SocketAddr,
54 pub auth: AuthWrite,
55}
56
57#[derive(Clone, Debug, PartialEq, Eq, Pack)]
58pub enum ClientHello {
59 ReadOnly(AuthRead),
62 WriteOnly(ClientHelloWrite),
69}
70
71#[derive(Clone, Debug, PartialEq, Eq, Pack)]
72pub struct ServerHelloWrite {
73 pub ttl: u64,
74 pub ttl_expired: bool,
75 pub auth: AuthWrite,
76 pub resolver_id: SocketAddr,
77}
78
79#[derive(Clone, Debug, PartialEq, Eq, Pack)]
80pub struct Secret(pub u128);
81
82#[derive(Clone, Debug, PartialEq, Eq)]
83pub struct ReadyForOwnershipCheck;
84
85impl Pack for ReadyForOwnershipCheck {
86 fn encoded_len(&self) -> usize {
87 len_wrapped_len(1)
88 }
89
90 fn encode(&self, buf: &mut impl BufMut) -> Result<()> {
91 len_wrapped_encode(buf, self, |buf| Ok(buf.put_u8(0)))
92 }
93
94 fn decode(buf: &mut impl Buf) -> Result<Self> {
95 len_wrapped_decode(buf, |buf| match <u8 as Pack>::decode(buf)? {
96 0 => Ok(ReadyForOwnershipCheck),
97 _ => Err(PackError::UnknownTag),
98 })
99 }
100}
101
102#[derive(Clone, Debug, PartialEq, Eq, Pack)]
103pub enum ToRead {
104 Resolve(Path),
106 List(Path),
108 Table(Path),
110 ListMatching(GlobSet),
112 GetChangeNr(Path),
114}
115
116#[derive(Clone, Debug, PartialEq, Eq, Pack)]
117pub enum Auth {
118 Anonymous,
119 Local { path: ArcStr },
120 Krb5 { spn: ArcStr },
121 Tls { name: ArcStr },
122}
123
124atomic_id!(PublisherId);
125
126#[derive(Clone, Debug, PartialEq, Eq, Pack)]
127pub enum TargetAuth {
128 Anonymous,
129 Local,
130 Krb5 { spn: ArcStr },
131 Tls { name: ArcStr },
132}
133
134impl TargetAuth {
135 pub fn is_anonymous(&self) -> bool {
136 match self {
137 Self::Anonymous => true,
138 Self::Krb5 { .. } | Self::Local | Self::Tls { .. } => false,
139 }
140 }
141}
142
143impl TryFrom<AuthWrite> for TargetAuth {
144 type Error = anyhow::Error;
145
146 fn try_from(v: AuthWrite) -> result::Result<Self, Self::Error> {
147 match v {
148 AuthWrite::Anonymous => Ok(Self::Anonymous),
149 AuthWrite::Local => Ok(Self::Local),
150 AuthWrite::Krb5 { spn } => Ok(Self::Krb5 { spn }),
151 AuthWrite::Reuse => bail!("no session to reuse"),
152 AuthWrite::Tls { name } => Ok(Self::Tls { name }),
153 }
154 }
155}
156
157#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Pack)]
158pub struct UserInfo {
159 pub name: ArcStr,
160 pub primary_group: ArcStr,
161 pub groups: SmallVec<[ArcStr; 16]>,
162 pub resolver: SocketAddr,
163 pub token: Bytes,
164}
165
166#[derive(Clone, Debug, PartialEq, Eq, Pack)]
167pub struct Publisher {
168 pub resolver: SocketAddr,
169 pub id: PublisherId,
170 pub addr: SocketAddr,
171 pub hash_method: HashMethod,
172 pub target_auth: TargetAuth,
173 #[pack(default)]
174 pub user_info: Option<UserInfo>,
175}
176
177#[derive(Clone, Debug, PartialEq, Eq, Pack)]
178pub struct PublisherRef {
179 pub id: PublisherId,
180 pub token: Bytes,
181}
182
183#[derive(Clone, Debug, PartialEq, Eq, Pack)]
184pub struct Resolved {
185 pub resolver: SocketAddr,
186 pub publishers: Pooled<Vec<PublisherRef>>,
187 pub timestamp: u64,
188 pub flags: u32,
189 pub permissions: u32,
190}
191
192#[derive(Clone, Debug, Pack)]
193pub struct Referral {
194 pub path: Path,
195 pub ttl: Option<u16>,
196 pub addrs: Pooled<Vec<(SocketAddr, Auth)>>,
197}
198
199impl Hash for Referral {
200 fn hash<H: Hasher>(&self, state: &mut H) {
201 for (addr, _) in &*self.addrs {
202 Hash::hash(&addr, state)
203 }
204 }
205}
206
207impl PartialEq for Referral {
208 fn eq(&self, other: &Referral) -> bool {
209 self.addrs.iter().zip(other.addrs.iter()).all(|(l, r)| l == r)
210 }
211}
212
213impl Eq for Referral {}
214
215#[derive(Clone, Debug, PartialEq, Eq, Pack)]
216pub struct Table {
217 pub rows: Pooled<Vec<Path>>,
218 pub cols: Pooled<Vec<(Path, Z64)>>,
219}
220
221#[derive(Clone, Debug, PartialEq, Eq, Pack)]
222pub struct ListMatching {
223 pub matched: Pooled<Vec<Pooled<Vec<Path>>>>,
224 pub referrals: Pooled<Vec<Referral>>,
225}
226
227#[derive(Clone, Debug, PartialEq, Eq, Pack)]
228pub struct GetChangeNr {
229 pub change_number: Z64,
230 pub resolver: SocketAddr,
231 pub referrals: Pooled<Vec<Referral>>,
232}
233
234#[derive(Clone, Debug, PartialEq, Eq, Pack)]
235pub enum FromRead {
236 Publisher(Publisher),
237 Resolved(Resolved),
238 List(Pooled<Vec<Path>>),
239 Table(Table),
240 Referral(Referral),
241 Denied,
242 Error(ArcStr),
243 ListMatching(ListMatching),
244 GetChangeNr(GetChangeNr),
245}
246
247#[derive(Clone, Debug, PartialEq, Eq, Hash, Pack)]
248pub enum ToWrite {
249 Publish(Path),
251 PublishDefault(Path),
253 Unpublish(Path),
255 Clear,
257 Heartbeat,
259 PublishWithFlags(Path, u32),
261 PublishDefaultWithFlags(Path, u32),
263 UnpublishDefault(Path),
265}
266
267#[derive(Clone, Debug, PartialEq, Eq, Hash, Pack)]
268pub enum FromWrite {
269 Published,
270 Unpublished,
271 Referral(Referral),
272 Denied,
273 Error(ArcStr),
274}