Coverage Report

Created: 2026-02-14 06:16

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ztunnel/src/dns/name_util.rs
Line
Count
Source
1
// Copyright Istio Authors
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
use hickory_proto::rr::Name;
16
17
/// Returns true if the given name ends with the labels provided by the domain iterator.
18
// TODO(nmittler): Consider upstreaming to TrustDNS.
19
0
pub fn has_domain(name: &Name, domain: &Name) -> bool {
20
0
    if domain.is_wildcard() || name.num_labels() <= domain.num_labels() {
21
0
        return false;
22
0
    }
23
24
0
    let name_iter = name.iter();
25
0
    let domain_iter = domain.iter();
26
27
    // Skip ahead to the start of the domain.
28
0
    let num_skip = name_iter.len() - domain_iter.len();
29
0
    let name_iter = name_iter.skip(num_skip);
30
31
    // Compare the remaining elements.
32
0
    name_iter.eq(domain_iter)
33
0
}
34
35
/// Trims the domain labels from the name. Returns `Some` if the domain was found and removed.
36
// TODO(nmittler): Consider upstreaming to TrustDNS.
37
0
pub fn trim_domain(name: &Name, domain: &Name) -> Option<Name> {
38
0
    if has_domain(name, domain) {
39
        // Create a Name from the labels leading up to the domain.
40
0
        let iter = name.iter();
41
0
        let num_labels = iter.len() - domain.num_labels() as usize;
42
0
        let mut name = Name::from_labels(iter.take(num_labels)).unwrap();
43
0
        name.set_fqdn(false);
44
0
        Some(name)
45
    } else {
46
0
        None
47
    }
48
0
}
49
50
#[cfg(test)]
51
mod tests {
52
    use super::*;
53
    use crate::test_helpers::dns::n;
54
    use hickory_proto::rr::Name;
55
56
    #[test]
57
    fn test_has_domain() {
58
        assert!(has_domain(&n("name.ns.svc.cluster.local"), &domain()));
59
60
        assert!(!has_domain(&n("name.ns.a.different.domain"), &domain()));
61
62
        assert!(!has_domain(&n("cluster.com"), &domain()));
63
    }
64
65
    #[test]
66
    fn test_trim_domain() {
67
        assert_eq!(
68
            Some(n("name.ns")),
69
            trim_domain(&n("name.ns.svc.cluster.local"), &domain())
70
        );
71
72
        assert_eq!(
73
            None,
74
            trim_domain(&n("name.ns.a.different.domain"), &domain())
75
        );
76
77
        // Can't trim if nothing left.
78
        assert_eq!(None, trim_domain(&n("svc.cluster.local"), &domain()));
79
    }
80
81
    fn domain() -> Name {
82
        n("svc.cluster.local")
83
    }
84
}