]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/recursordist/settings/rust-bridge-in.rs
Make a isValidHostname() callable from Rust that calls into DNSName::is_hostname()
[thirdparty/pdns.git] / pdns / recursordist / settings / rust-bridge-in.rs
1 // This file (rust-bridge-in.rs) is included into lib.rs inside the bridge module
2 /*
3 * Implement non-generated structs that need to be handled by Serde and CXX
4 */
5
6 // A single forward zone
7 #[derive(Deserialize, Serialize, Debug, PartialEq)]
8 #[serde(deny_unknown_fields)]
9 pub struct ForwardZone {
10 #[serde(default, skip_serializing_if = "crate::is_default")]
11 zone: String,
12 #[serde(default, skip_serializing_if = "crate::is_default")]
13 forwarders: Vec<String>,
14 #[serde(default, skip_serializing_if = "crate::is_default")]
15 recurse: bool,
16 #[serde(default, skip_serializing_if = "crate::is_default")]
17 notify_allowed: bool,
18 }
19
20 // A single auth zone
21 #[derive(Deserialize, Serialize, Debug, PartialEq)]
22 #[serde(deny_unknown_fields)]
23 pub struct AuthZone {
24 #[serde(default, skip_serializing_if = "crate::is_default")]
25 zone: String,
26 #[serde(default, skip_serializing_if = "crate::is_default")]
27 file: String,
28 }
29
30 // A single trust anchor
31 #[derive(Deserialize, Serialize, Debug, PartialEq)]
32 #[serde(deny_unknown_fields)]
33 pub struct TrustAnchor {
34 #[serde(default, skip_serializing_if = "crate::is_default")]
35 name: String,
36 #[serde(default, skip_serializing_if = "crate::is_default")]
37 dsrecords: Vec<String>,
38 }
39
40 // A single negative trust anchor
41 #[derive(Deserialize, Serialize, Debug, PartialEq)]
42 #[serde(deny_unknown_fields)]
43 pub struct NegativeTrustAnchor {
44 #[serde(default, skip_serializing_if = "crate::is_default")]
45 name: String,
46 #[serde(default, skip_serializing_if = "crate::is_default")]
47 reason: String,
48 }
49
50 // A protobuf logging server
51 #[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
52 #[serde(deny_unknown_fields)]
53 pub struct ProtobufServer {
54 #[serde(default, skip_serializing_if = "crate::is_default")]
55 servers: Vec<String>,
56 #[serde(default = "crate::U64::<2>::value", skip_serializing_if = "crate::U64::<2>::is_equal")]
57 timeout: u64,
58 #[serde(default = "crate::U64::<100>::value", skip_serializing_if = "crate::U64::<100>::is_equal")]
59 maxQueuedEntries: u64,
60 #[serde(default = "crate::U64::<1>::value", skip_serializing_if = "crate::U64::<1>::is_equal")]
61 reconnectWaitTime: u64,
62 #[serde(default, skip_serializing_if = "crate::is_default")]
63 taggedOnly: bool,
64 #[serde(default, skip_serializing_if = "crate::is_default")]
65 asyncConnect: bool,
66 #[serde(default = "crate::Bool::<true>::value", skip_serializing_if = "crate::if_true")]
67 logQueries: bool,
68 #[serde(default = "crate::Bool::<true>::value", skip_serializing_if = "crate::if_true")]
69 logResponses: bool,
70 #[serde(default = "crate::def_pb_export_qtypes", skip_serializing_if = "crate::default_value_equal_pb_export_qtypes")]
71 exportTypes: Vec<String>,
72 #[serde(default, skip_serializing_if = "crate::is_default")]
73 logMappedFrom: bool,
74 }
75
76 // A dnstap logging server
77 #[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
78 #[serde(deny_unknown_fields)]
79 pub struct DNSTapFrameStreamServer {
80 #[serde(default, skip_serializing_if = "crate::is_default")]
81 servers: Vec<String>,
82 #[serde(default = "crate::Bool::<true>::value", skip_serializing_if = "crate::if_true")]
83 logQueries: bool,
84 #[serde(default = "crate::Bool::<true>::value", skip_serializing_if = "crate::if_true")]
85 logResponses: bool,
86 #[serde(default, skip_serializing_if = "crate::is_default")]
87 bufferHint: u64,
88 #[serde(default, skip_serializing_if = "crate::is_default")]
89 flushTimeout: u64,
90 #[serde(default, skip_serializing_if = "crate::is_default")]
91 inputQueueSize: u64,
92 #[serde(default, skip_serializing_if = "crate::is_default")]
93 outputQueueSize: u64,
94 #[serde(default, skip_serializing_if = "crate::is_default")]
95 queueNotifyThreshold: u64,
96 #[serde(default, skip_serializing_if = "crate::is_default")]
97 reopenInterval: u64,
98 }
99
100 // A dnstap logging NOD server
101 #[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
102 #[serde(deny_unknown_fields)]
103 pub struct DNSTapNODFrameStreamServer {
104 #[serde(default, skip_serializing_if = "crate::is_default")]
105 servers: Vec<String>,
106 #[serde(default = "crate::Bool::<true>::value", skip_serializing_if = "crate::if_true")]
107 logNODs: bool,
108 #[serde(default, skip_serializing_if = "crate::is_default")]
109 logUDRs: bool,
110 #[serde(default, skip_serializing_if = "crate::is_default")]
111 bufferHint: u64,
112 #[serde(default, skip_serializing_if = "crate::is_default")]
113 flushTimeout: u64,
114 #[serde(default, skip_serializing_if = "crate::is_default")]
115 inputQueueSize: u64,
116 #[serde(default, skip_serializing_if = "crate::is_default")]
117 outputQueueSize: u64,
118 #[serde(default, skip_serializing_if = "crate::is_default")]
119 queueNotifyThreshold: u64,
120 #[serde(default, skip_serializing_if = "crate::is_default")]
121 reopenInterval: u64,
122 }
123
124 #[derive(Default, Deserialize, Serialize, Clone, Debug, PartialEq)]
125 #[serde(deny_unknown_fields)]
126 pub struct TSIGTriplet {
127 #[serde(default, skip_serializing_if = "crate::is_default")]
128 name: String,
129 #[serde(default, skip_serializing_if = "crate::is_default")]
130 algo: String,
131 #[serde(default, skip_serializing_if = "crate::is_default")]
132 secret: String,
133 }
134
135 #[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
136 #[serde(deny_unknown_fields)]
137 pub struct RPZ {
138 #[serde(default, skip_serializing_if = "crate::is_default")]
139 name: String,
140 #[serde(default, skip_serializing_if = "crate::is_default")]
141 addresses: Vec<String>,
142 #[serde(default, skip_serializing_if = "crate::is_default")]
143 defcontent: String,
144 #[serde(default, skip_serializing_if = "crate::is_default")]
145 defpol: String,
146 #[serde(default = "crate::Bool::<true>::value", skip_serializing_if = "crate::if_true")]
147 defpolOverrideLocalData: bool,
148 #[serde(default = "crate::U32::<{u32::MAX}>::value", skip_serializing_if = "crate::U32::<{u32::MAX}>::is_equal")]
149 defttl: u32,
150 #[serde(default = "crate::U32::<{u32::MAX}>::value", skip_serializing_if = "crate::U32::<{u32::MAX}>::is_equal")]
151 extendedErrorCode: u32,
152 #[serde(default, skip_serializing_if = "crate::is_default")]
153 extendedErrorExtra: String,
154 #[serde(default, skip_serializing_if = "crate::is_default")]
155 includeSOA: bool,
156 #[serde(default, skip_serializing_if = "crate::is_default")]
157 ignoreDuplicates: bool,
158 #[serde(default = "crate::U32::<{u32::MAX}>::value", skip_serializing_if = "crate::U32::<{u32::MAX}>::is_equal")]
159 maxTTL: u32,
160 #[serde(default, skip_serializing_if = "crate::is_default")]
161 policyName: String,
162 #[serde(default, skip_serializing_if = "crate::is_default")]
163 tags: Vec<String>,
164 #[serde(default = "crate::Bool::<true>::value", skip_serializing_if = "crate::if_true")]
165 overridesGettag: bool,
166 #[serde(default, skip_serializing_if = "crate::is_default")]
167 zoneSizeHint: u32,
168 #[serde(default, skip_serializing_if = "crate::is_default")]
169 tsig: TSIGTriplet,
170 #[serde(default, skip_serializing_if = "crate::is_default")]
171 refresh: u32,
172 #[serde(default, skip_serializing_if = "crate::is_default")]
173 maxReceivedMBytes: u32,
174 #[serde(default, skip_serializing_if = "crate::is_default")]
175 localAddress: String,
176 #[serde(default = "crate::U32::<20>::value", skip_serializing_if = "crate::U32::<20>::is_equal")]
177 axfrTimeout: u32,
178 #[serde(default, skip_serializing_if = "crate::is_default")]
179 dumpFile: String,
180 #[serde(default, skip_serializing_if = "crate::is_default")]
181 seedFile: String,
182 }
183
184 #[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
185 #[serde(deny_unknown_fields)]
186 pub struct ZoneToCache {
187 #[serde(default, skip_serializing_if = "crate::is_default")]
188 zone: String,
189 #[serde(default, skip_serializing_if = "crate::is_default")]
190 method: String,
191 #[serde(default, skip_serializing_if = "crate::is_default")]
192 sources: Vec<String>,
193 #[serde(default = "crate::U64::<20>::value", skip_serializing_if = "crate::U64::<20>::is_equal")]
194 timeout: u64,
195 #[serde(default, skip_serializing_if = "crate::is_default")]
196 tsig: TSIGTriplet,
197 #[serde(default = "crate::U64::<86400>::value", skip_serializing_if = "crate::U64::<86400>::is_equal")]
198 refreshPeriod: u64,
199 #[serde(default = "crate::U64::<60>::value", skip_serializing_if = "crate::U64::<60>::is_equal")]
200 retryOnErrorPeriod: u64,
201 #[serde(default, skip_serializing_if = "crate::is_default")]
202 maxReceivedMBytes: u64,
203 #[serde(default, skip_serializing_if = "crate::is_default")]
204 localAddress: String,
205 #[serde(default = "crate::def_ztc_validate", skip_serializing_if = "crate::def_value_equals_ztc_validate")]
206 zonemd: String,
207 #[serde(default = "crate::def_ztc_validate", skip_serializing_if = "crate::def_value_equals_ztc_validate")]
208 dnssec: String,
209 }
210
211 #[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
212 #[serde(deny_unknown_fields)]
213 pub struct SubnetOrder {
214 #[serde(default, skip_serializing_if = "crate::is_default")]
215 subnet: String,
216 #[serde(default, skip_serializing_if = "crate::is_default")]
217 order: u32,
218 }
219
220 #[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
221 #[serde(deny_unknown_fields)]
222 pub struct SortList {
223 #[serde(default, skip_serializing_if = "crate::is_default")]
224 key: String,
225 #[serde(default, skip_serializing_if = "crate::is_default")]
226 subnets: Vec<SubnetOrder>,
227 }
228
229 #[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
230 #[serde(deny_unknown_fields)]
231 pub struct AllowedAdditionalQType {
232 #[serde(default, skip_serializing_if = "crate::is_default")]
233 qtype: String,
234 #[serde(default, skip_serializing_if = "crate::is_default")]
235 targets: Vec<String>,
236 #[serde(default = "crate::def_additional_mode", skip_serializing_if = "crate::default_value_equals_additional_mode")]
237 mode: String,
238 }
239
240 #[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
241 #[serde(deny_unknown_fields)]
242 pub struct ProxyMapping {
243 #[serde(default, skip_serializing_if = "crate::is_default")]
244 subnet: String,
245 #[serde(default, skip_serializing_if = "crate::is_default")]
246 address: String,
247 #[serde(default, skip_serializing_if = "crate::is_default")]
248 domains: Vec<String>,
249 }
250
251 // A struct holding both a vector of forward zones and a vector o auth zones, used by REST API code
252 #[derive(Deserialize, Serialize, Debug, PartialEq)]
253 #[serde(deny_unknown_fields)]
254 pub struct ApiZones {
255 #[serde(default, skip_serializing_if = "crate::is_default")]
256 auth_zones: Vec<AuthZone>,
257 #[serde(default, skip_serializing_if = "crate::is_default")]
258 forward_zones: Vec<ForwardZone>,
259 }
260
261 // Two structs used to generated YAML based on a vector of name to value mappings
262 // Cannot use Enum as CXX has only very basic Enum support
263 struct Value {
264 bool_val: bool,
265 u64_val: u64,
266 f64_val: f64,
267 string_val: String,
268 vec_string_val: Vec<String>,
269 vec_forwardzone_val: Vec<ForwardZone>,
270 vec_authzone_val: Vec<AuthZone>,
271 vec_trustanchor_val: Vec<TrustAnchor>,
272 vec_negativetrustanchor_val: Vec<NegativeTrustAnchor>,
273 vec_protobufserver_val: Vec<ProtobufServer>,
274 vec_dnstap_framestream_server_val: Vec<DNSTapFrameStreamServer>,
275 vec_dnstap_nod_framestream_server_val: Vec<DNSTapNODFrameStreamServer>,
276 vec_rpz_val: Vec<RPZ>,
277 vec_sortlist_val: Vec<SortList>,
278 vec_zonetocache_val: Vec<ZoneToCache>,
279 vec_allowedadditionalqtype_val: Vec<AllowedAdditionalQType>,
280 vec_proxymapping_val: Vec<ProxyMapping>,
281 }
282
283 struct OldStyle {
284 section: String,
285 name: String,
286 old_name: String,
287 type_name: String,
288 value: Value,
289 overriding: bool,
290 }
291
292 /*
293 * Functions callable from C++
294 */
295 extern "Rust" {
296 // Parse a string representing YAML text and produce the corresponding data structure known to Serde
297 // The settings that can be stored in individual files get their own parse function
298 // Main recursor settings
299 fn parse_yaml_string(str: &str) -> Result<Recursorsettings>;
300 // Allow from sequence
301 fn parse_yaml_string_to_allow_from(str: &str) -> Result<Vec<String>>;
302 // Forward zones sequence
303 fn parse_yaml_string_to_forward_zones(str: &str) -> Result<Vec<ForwardZone>>;
304 // Allow notify for sequence
305 fn parse_yaml_string_to_allow_notify_for(str: &str) -> Result<Vec<String>>;
306 // REST API zones
307 fn parse_yaml_string_to_api_zones(str: &str) -> Result<ApiZones>;
308
309 // Prdoduce a YAML formatted string given a data structure known to Serde
310 fn to_yaml_string(self: &Recursorsettings) -> Result<String>;
311 // When doing a conversion of old-style to YAML style we use a vector of OldStyle structs
312 fn map_to_yaml_string(map: &Vec<OldStyle>) -> Result<String>;
313 fn forward_zones_to_yaml_string(vec: &Vec<ForwardZone>) -> Result<String>;
314 fn allow_from_to_yaml_string(vec: &Vec<String>) -> Result<String>;
315 fn allow_from_to_yaml_string_incoming(key: &String, filekey: &String, vec: &Vec<String>) -> Result<String>;
316 fn allow_for_to_yaml_string(vec: &Vec<String>) -> Result<String>;
317
318 // Merge a string representing YAML settings into a existing setttings struct
319 fn merge(lhs: &mut Recursorsettings, rhs: &str) -> Result<()>;
320
321 // Validate the sections inside the main settings struct, sections themselves will valdiate their fields
322 fn validate(self: &Recursorsettings) -> Result<()>;
323 // The validate function below are "hand-crafted" as their structs are not generated
324 fn validate(self: &AuthZone, field: &str) -> Result<()>;
325 fn validate(self: &ForwardZone, field: &str) -> Result<()>;
326 fn validate(self: &TrustAnchor, field: &str) -> Result<()>;
327 fn validate(self: &NegativeTrustAnchor, field: &str) -> Result<()>;
328 fn validate(self: &ApiZones, field: &str) -> Result<()>;
329
330 // Helper functions to call the proper validate function on vectors of various kinds
331 fn validate_auth_zones(field: &str, vec: &Vec<AuthZone>) -> Result<()>;
332 fn validate_forward_zones(field: &str, vec: &Vec<ForwardZone>) -> Result<()>;
333 fn validate_allow_for(field: &str, vec: &Vec<String>) -> Result<()>;
334 fn validate_allow_notify_for(field: &str, vec: &Vec<String>) -> Result<()>;
335 fn validate_allow_from(field: &str, vec: &Vec<String>) -> Result<()>;
336
337 // The functions to maintain REST API managed zones
338 fn api_read_zones(path: &str) -> Result<UniquePtr<ApiZones>>;
339 fn api_add_auth_zone(file: &str, authzone: AuthZone) -> Result<()>;
340 fn api_add_forward_zone(file: &str, forwardzone: ForwardZone) -> Result<()>;
341 fn api_add_forward_zones(file: &str, forwardzones: &mut Vec<ForwardZone>) -> Result<()>;
342 fn validate_trustanchors(field: &str, vec: &Vec<TrustAnchor>) -> Result<()>;
343 fn validate_negativetrustanchors(field: &str, vec: &Vec<NegativeTrustAnchor>) -> Result<()>;
344 fn api_delete_zone(file: &str, zone: &str) -> Result<()>;
345 }
346
347 unsafe extern "C++" {
348 include!("bridge.hh");
349 fn qTypeStringToCode(name: &str) -> u16;
350 fn isValidHostname(name: &str) -> bool;
351 }