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::global::GPooled;
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 #[pack(default)]
56 pub priority: PublisherPriority,
57}
58
59#[derive(Clone, Debug, PartialEq, Eq, Pack)]
60pub enum ClientHello {
61 ReadOnly(AuthRead),
64 WriteOnly(ClientHelloWrite),
71}
72
73#[derive(Clone, Debug, PartialEq, Eq, Pack)]
74pub struct ServerHelloWrite {
75 pub ttl: u64,
76 pub ttl_expired: bool,
77 pub auth: AuthWrite,
78 pub resolver_id: SocketAddr,
79}
80
81#[derive(Clone, Debug, PartialEq, Eq, Pack)]
82pub struct Secret(pub u128);
83
84#[derive(Clone, Debug, PartialEq, Eq)]
85pub struct ReadyForOwnershipCheck;
86
87impl Pack for ReadyForOwnershipCheck {
88 fn encoded_len(&self) -> usize {
89 len_wrapped_len(1)
90 }
91
92 fn encode(&self, buf: &mut impl BufMut) -> Result<()> {
93 len_wrapped_encode(buf, self, |buf| Ok(buf.put_u8(0)))
94 }
95
96 fn decode(buf: &mut impl Buf) -> Result<Self> {
97 len_wrapped_decode(buf, |buf| match <u8 as Pack>::decode(buf)? {
98 0 => Ok(ReadyForOwnershipCheck),
99 _ => Err(PackError::UnknownTag),
100 })
101 }
102}
103
104#[derive(Clone, Debug, PartialEq, Eq, Pack)]
105pub enum ToRead {
106 Resolve(Path),
108 List(Path),
110 Table(Path),
112 ListMatching(GlobSet),
114 GetChangeNr(Path),
116}
117
118#[derive(Clone, Debug, PartialEq, Eq, Pack)]
119pub enum Auth {
120 Anonymous,
121 Local { path: ArcStr },
122 Krb5 { spn: ArcStr },
123 Tls { name: ArcStr },
124}
125
126atomic_id!(PublisherId);
127
128#[derive(Clone, Debug, PartialEq, Eq, Pack)]
129pub enum TargetAuth {
130 Anonymous,
131 Local,
132 Krb5 { spn: ArcStr },
133 Tls { name: ArcStr },
134}
135
136impl TargetAuth {
137 pub fn is_anonymous(&self) -> bool {
138 match self {
139 Self::Anonymous => true,
140 Self::Krb5 { .. } | Self::Local | Self::Tls { .. } => false,
141 }
142 }
143}
144
145impl TryFrom<AuthWrite> for TargetAuth {
146 type Error = anyhow::Error;
147
148 fn try_from(v: AuthWrite) -> result::Result<Self, Self::Error> {
149 match v {
150 AuthWrite::Anonymous => Ok(Self::Anonymous),
151 AuthWrite::Local => Ok(Self::Local),
152 AuthWrite::Krb5 { spn } => Ok(Self::Krb5 { spn }),
153 AuthWrite::Reuse => bail!("no session to reuse"),
154 AuthWrite::Tls { name } => Ok(Self::Tls { name }),
155 }
156 }
157}
158
159#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Pack)]
160pub struct UserInfo {
161 pub name: ArcStr,
162 pub primary_group: ArcStr,
163 pub groups: SmallVec<[ArcStr; 16]>,
164 pub resolver: SocketAddr,
165 pub token: Bytes,
166}
167
168#[derive(Clone, Copy, Debug, PartialEq, Eq, Pack)]
169pub enum PublisherPriority {
170 High,
171 Normal,
172 Low,
173}
174
175impl Default for PublisherPriority {
176 fn default() -> Self {
177 PublisherPriority::Normal
178 }
179}
180
181#[derive(Clone, Debug, PartialEq, Eq, Pack)]
182pub struct Publisher {
183 pub resolver: SocketAddr,
184 pub id: PublisherId,
185 pub addr: SocketAddr,
186 pub hash_method: HashMethod,
187 pub target_auth: TargetAuth,
188 #[pack(default)]
189 pub user_info: Option<UserInfo>,
190 #[pack(default)]
191 pub priority: PublisherPriority,
192}
193
194#[derive(Clone, Debug, PartialEq, Eq, Pack)]
195pub struct PublisherRef {
196 pub id: PublisherId,
197 pub token: Bytes,
198}
199
200#[derive(Clone, Debug, PartialEq, Eq, Pack)]
202pub struct Resolved {
203 pub resolver: SocketAddr,
204 pub publishers: GPooled<Vec<PublisherRef>>,
205 pub timestamp: u64,
206 pub flags: u32,
207 pub permissions: u32,
208}
209
210#[derive(Clone, Debug, Pack)]
211pub struct Referral {
212 pub path: Path,
213 pub ttl: Option<u16>,
214 pub addrs: GPooled<Vec<(SocketAddr, Auth)>>,
215}
216
217impl Hash for Referral {
218 fn hash<H: Hasher>(&self, state: &mut H) {
219 for (addr, _) in &*self.addrs {
220 Hash::hash(&addr, state)
221 }
222 }
223}
224
225impl PartialEq for Referral {
226 fn eq(&self, other: &Referral) -> bool {
227 self.addrs.iter().zip(other.addrs.iter()).all(|(l, r)| l == r)
228 }
229}
230
231impl Eq for Referral {}
232
233#[derive(Clone, Debug, PartialEq, Eq, Pack)]
235pub struct Table {
236 pub rows: GPooled<Vec<Path>>,
237 pub cols: GPooled<Vec<(Path, Z64)>>,
238}
239
240#[derive(Clone, Debug, PartialEq, Eq, Pack)]
241pub struct ListMatching {
242 pub matched: GPooled<Vec<GPooled<Vec<Path>>>>,
243 pub referrals: GPooled<Vec<Referral>>,
244}
245
246#[derive(Clone, Debug, PartialEq, Eq, Pack)]
247pub struct GetChangeNr {
248 pub change_number: Z64,
249 pub resolver: SocketAddr,
250 pub referrals: GPooled<Vec<Referral>>,
251}
252
253#[derive(Clone, Debug, PartialEq, Eq, Pack)]
254pub enum FromRead {
255 Publisher(Publisher),
256 Resolved(Resolved),
257 List(GPooled<Vec<Path>>),
258 Table(Table),
259 Referral(Referral),
260 Denied,
261 Error(ArcStr),
262 ListMatching(ListMatching),
263 GetChangeNr(GetChangeNr),
264}
265
266#[derive(Clone, Debug, PartialEq, Eq, Hash, Pack)]
267pub enum ToWrite {
268 Publish(Path),
270 PublishDefault(Path),
272 Unpublish(Path),
274 Clear,
276 Heartbeat,
278 PublishWithFlags(Path, u32),
280 PublishDefaultWithFlags(Path, u32),
282 UnpublishDefault(Path),
284}
285
286#[derive(Clone, Debug, PartialEq, Eq, Hash, Pack)]
287pub enum FromWrite {
288 Published,
289 Unpublished,
290 Referral(Referral),
291 Denied,
292 Error(ArcStr),
293}