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)]
201pub struct Resolved {
202 pub resolver: SocketAddr,
203 pub publishers: GPooled<Vec<PublisherRef>>,
204 pub timestamp: u64,
205 pub flags: u32,
206 pub permissions: u32,
207}
208
209#[derive(Clone, Debug, Pack)]
210pub struct Referral {
211 pub path: Path,
212 pub ttl: Option<u16>,
213 pub addrs: GPooled<Vec<(SocketAddr, Auth)>>,
214}
215
216impl Hash for Referral {
217 fn hash<H: Hasher>(&self, state: &mut H) {
218 for (addr, _) in &*self.addrs {
219 Hash::hash(&addr, state)
220 }
221 }
222}
223
224impl PartialEq for Referral {
225 fn eq(&self, other: &Referral) -> bool {
226 self.addrs.iter().zip(other.addrs.iter()).all(|(l, r)| l == r)
227 }
228}
229
230impl Eq for Referral {}
231
232#[derive(Clone, Debug, PartialEq, Eq, Pack)]
233pub struct Table {
234 pub rows: GPooled<Vec<Path>>,
235 pub cols: GPooled<Vec<(Path, Z64)>>,
236}
237
238#[derive(Clone, Debug, PartialEq, Eq, Pack)]
239pub struct ListMatching {
240 pub matched: GPooled<Vec<GPooled<Vec<Path>>>>,
241 pub referrals: GPooled<Vec<Referral>>,
242}
243
244#[derive(Clone, Debug, PartialEq, Eq, Pack)]
245pub struct GetChangeNr {
246 pub change_number: Z64,
247 pub resolver: SocketAddr,
248 pub referrals: GPooled<Vec<Referral>>,
249}
250
251#[derive(Clone, Debug, PartialEq, Eq, Pack)]
252pub enum FromRead {
253 Publisher(Publisher),
254 Resolved(Resolved),
255 List(GPooled<Vec<Path>>),
256 Table(Table),
257 Referral(Referral),
258 Denied,
259 Error(ArcStr),
260 ListMatching(ListMatching),
261 GetChangeNr(GetChangeNr),
262}
263
264#[derive(Clone, Debug, PartialEq, Eq, Hash, Pack)]
265pub enum ToWrite {
266 Publish(Path),
268 PublishDefault(Path),
270 Unpublish(Path),
272 Clear,
274 Heartbeat,
276 PublishWithFlags(Path, u32),
278 PublishDefaultWithFlags(Path, u32),
280 UnpublishDefault(Path),
282}
283
284#[derive(Clone, Debug, PartialEq, Eq, Hash, Pack)]
285pub enum FromWrite {
286 Published,
287 Unpublished,
288 Referral(Referral),
289 Denied,
290 Error(ArcStr),
291}