Coverage Report

Created: 2025-09-12 10:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/root/doris/be/src/util/cidr.cpp
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
#include "util/cidr.h"
19
20
#include <arpa/inet.h>
21
#include <sys/socket.h>
22
23
#include <algorithm>
24
#include <cstddef>
25
#include <exception>
26
#include <iterator>
27
#include <ostream>
28
29
#include "common/logging.h"
30
31
namespace doris {
32
#include "common/compile_check_avoid_begin.h"
33
34
constexpr std::uint8_t kIPv4Bits = 32;
35
constexpr std::uint8_t kIPv6Bits = 128;
36
37
32
bool CIDR::reset(const std::string& cidr_str) {
38
32
    auto slash = std::find(std::begin(cidr_str), std::end(cidr_str), '/');
39
32
    auto ip = (slash == std::end(cidr_str)) ? cidr_str
40
32
                                            : cidr_str.substr(0, slash - std::begin(cidr_str));
41
42
32
    if (inet_pton(AF_INET, ip.c_str(), _address.data())) {
43
24
        _family = AF_INET;
44
24
        _netmask_len = kIPv4Bits;
45
24
    } else if (inet_pton(AF_INET6, ip.c_str(), _address.data())) {
46
3
        _family = AF_INET6;
47
3
        _netmask_len = kIPv6Bits;
48
5
    } else {
49
5
        LOG(WARNING) << "Wrong CIDRIP format. network=" << cidr_str;
50
5
        return false;
51
5
    }
52
53
27
    if (slash == std::end(cidr_str)) {
54
15
        return true;
55
15
    }
56
57
12
    std::size_t pos;
58
12
    std::string suffix = std::string(slash + 1, std::end(cidr_str));
59
12
    int len;
60
12
    try {
61
12
        len = std::stoi(suffix, &pos);
62
12
    } catch (const std::exception& e) {
63
2
        LOG(WARNING) << "Wrong CIDR format. network=" << cidr_str << ", reason=" << e.what();
64
2
        return false;
65
2
    }
66
67
10
    if (pos != suffix.size()) {
68
0
        LOG(WARNING) << "Wrong CIDR format. network=" << cidr_str;
69
0
        return false;
70
0
    }
71
72
10
    if (len < 0 || len > _netmask_len) {
73
0
        LOG(WARNING) << "Wrong CIDR mask format. network=" << cidr_str;
74
0
        return false;
75
0
    }
76
10
    _netmask_len = len;
77
10
    return true;
78
10
}
79
80
14
bool CIDR::contains(const CIDR& ip) const {
81
14
    if ((_family != ip._family) || (_netmask_len > ip._netmask_len)) {
82
0
        return false;
83
0
    }
84
14
    auto bytes = _netmask_len / 8;
85
14
    auto cidr_begin = _address.cbegin();
86
14
    auto ip_begin = ip._address.cbegin();
87
14
    if (!std::equal(cidr_begin, cidr_begin + bytes, ip_begin, ip_begin + bytes)) {
88
5
        return false;
89
5
    }
90
9
    if ((_netmask_len % 8) == 0) {
91
7
        return true;
92
7
    }
93
2
    auto mask = (0xFF << (8 - (_netmask_len % 8))) & 0xFF;
94
2
    return (_address[bytes] & mask) == (ip._address[bytes] & mask);
95
9
}
96
97
#include "common/compile_check_avoid_end.h"
98
} // end namespace doris