Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2022 Project CHIP Authors
4 : *
5 : * Licensed under the Apache License, Version 2.0 (the "License");
6 : * you may not use this file except in compliance with the License.
7 : * 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, software
12 : * distributed under the License is distributed on an "AS IS" BASIS,
13 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 : * See the License for the specific language governing permissions and
15 : * limitations under the License.
16 : */
17 :
18 : #include <lib/dnssd/IPAddressSorter.h>
19 : #include <lib/support/SortUtils.h>
20 :
21 : namespace chip {
22 : namespace Dnssd {
23 : namespace IPAddressSorter {
24 :
25 13 : void Sort(Inet::IPAddress * addresses, size_t count, Inet::InterfaceId interfaceId)
26 : {
27 13 : Sorting::InsertionSort(addresses, count, [interfaceId](const Inet::IPAddress & a, const Inet::IPAddress & b) -> bool {
28 13 : auto scoreA = to_underlying(ScoreIpAddress(a, interfaceId));
29 13 : auto scoreB = to_underlying(ScoreIpAddress(b, interfaceId));
30 13 : return scoreA > scoreB;
31 : });
32 13 : }
33 :
34 0 : void Sort(const Span<Inet::IPAddress> & addresses, Inet::InterfaceId interfaceId)
35 : {
36 0 : Sorting::InsertionSort(addresses.data(), addresses.size(),
37 0 : [interfaceId](const Inet::IPAddress & a, const Inet::IPAddress & b) -> bool {
38 0 : auto scoreA = to_underlying(ScoreIpAddress(a, interfaceId));
39 0 : auto scoreB = to_underlying(ScoreIpAddress(b, interfaceId));
40 0 : return scoreA > scoreB;
41 : });
42 0 : }
43 :
44 126 : IpScore ScoreIpAddress(const Inet::IPAddress & ip, Inet::InterfaceId interfaceId)
45 : {
46 126 : if (ip.IsIPv6())
47 : {
48 114 : if (ip.IsIPv6LinkLocal())
49 : {
50 16 : return IpScore::kLinkLocal;
51 : }
52 :
53 98 : if (interfaceId.MatchLocalIPv6Subnet(ip))
54 : {
55 0 : if (ip.IsIPv6GlobalUnicast())
56 : {
57 0 : return IpScore::kGlobalUnicastWithSharedPrefix;
58 : }
59 0 : if (ip.IsIPv6ULA())
60 : {
61 0 : return IpScore::kUniqueLocalWithSharedPrefix;
62 : }
63 : }
64 98 : if (ip.IsIPv6GlobalUnicast())
65 : {
66 4 : return IpScore::kGlobalUnicast;
67 : }
68 :
69 94 : if (ip.IsIPv6ULA())
70 : {
71 94 : return IpScore::kUniqueLocal;
72 : }
73 :
74 0 : return IpScore::kOtherIpv6;
75 : }
76 :
77 12 : return IpScore::kIpv4;
78 : }
79 :
80 : } // namespace IPAddressSorter
81 : } // namespace Dnssd
82 : } // namespace chip
|