-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Dnssd] Sort IPs by scores for commissionable node discovery
- Loading branch information
1 parent
66c0270
commit d843881
Showing
7 changed files
with
173 additions
and
87 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
/* | ||
* | ||
* Copyright (c) 2022 Project CHIP Authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
#include <lib/dnssd/IPAddressSorter.h> | ||
#include <lib/support/SortUtils.h> | ||
|
||
namespace chip { | ||
namespace Dnssd { | ||
|
||
void IPAddressSorter::Sort(Inet::IPAddress * addresses, size_t count, Inet::InterfaceId interfaceId) | ||
{ | ||
Sorting::BubbleSort(addresses, count, [interfaceId](const Inet::IPAddress & a, const Inet::IPAddress & b) -> bool { | ||
auto scoreA = to_underlying(ScoreIpAddress(a, interfaceId)); | ||
auto scoreB = to_underlying(ScoreIpAddress(b, interfaceId)); | ||
return scoreA > scoreB; | ||
}); | ||
} | ||
|
||
void IPAddressSorter::Sort(const Span<Inet::IPAddress> & addresses, Inet::InterfaceId interfaceId) | ||
{ | ||
Sorting::BubbleSort(addresses.begin(), addresses.size(), | ||
[interfaceId](const Inet::IPAddress & a, const Inet::IPAddress & b) -> bool { | ||
auto scoreA = to_underlying(ScoreIpAddress(a, interfaceId)); | ||
auto scoreB = to_underlying(ScoreIpAddress(b, interfaceId)); | ||
return scoreA > scoreB; | ||
}); | ||
} | ||
|
||
IpScore IPAddressSorter::ScoreIpAddress(const Inet::IPAddress & ip, Inet::InterfaceId interfaceId) | ||
{ | ||
if (ip.IsIPv6()) | ||
{ | ||
#ifdef __APPLE__ | ||
if (ip.IsIPv6LinkLocal()) | ||
{ | ||
return IpScore::kLinkLocal; | ||
} | ||
#endif // __APPLE__ | ||
|
||
if (interfaceId.MatchLocalIPv6Subnet(ip)) | ||
{ | ||
if (ip.IsIPv6GlobalUnicast()) | ||
{ | ||
return IpScore::kGlobalUnicastWithSharedPrefix; | ||
} | ||
if (ip.IsIPv6ULA()) | ||
{ | ||
return IpScore::kUniqueLocalWithSharedPrefix; | ||
} | ||
} | ||
if (ip.IsIPv6GlobalUnicast()) | ||
{ | ||
return IpScore::kGlobalUnicast; | ||
} | ||
|
||
if (ip.IsIPv6ULA()) | ||
{ | ||
return IpScore::kUniqueLocal; | ||
} | ||
|
||
#ifndef __APPLE__ | ||
if (ip.IsIPv6LinkLocal()) | ||
{ | ||
return IpScore::kLinkLocal; | ||
} | ||
#endif // __APPLE__ | ||
|
||
return IpScore::kOtherIpv6; | ||
} | ||
|
||
return IpScore::kIpv4; | ||
} | ||
|
||
} // namespace Dnssd | ||
} // namespace chip |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
/* | ||
* | ||
* Copyright (c) 2022 Project CHIP Authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
#pragma once | ||
|
||
#include <inet/IPAddress.h> | ||
#include <lib/support/Span.h> | ||
|
||
namespace chip { | ||
namespace Dnssd { | ||
|
||
// IP addess "suitability" | ||
// - Larger value means "more suitable" | ||
// - Enum ordered ascending for easier read. Note however that order of | ||
// checks MUST match in ScoreIpAddress below. | ||
enum class IpScore : unsigned | ||
{ | ||
kInvalid = 0, // No address available | ||
|
||
// "Other" IPv6 include: | ||
// - invalid addresses (have seen router bugs during interop testing) | ||
// - embedded IPv4 (::/80) | ||
kOtherIpv6 = 1, | ||
kIpv4 = 2, // Not Matter SPEC, so low priority | ||
#ifdef __APPLE__ | ||
kUniqueLocal = 3, // ULA. Thread devices use this | ||
kGlobalUnicast = 4, // Maybe routable, not local subnet | ||
kUniqueLocalWithSharedPrefix = 5, // Prefix seems to match a local interface | ||
kGlobalUnicastWithSharedPrefix = 6, // Prefix seems to match a local interface | ||
kLinkLocal = 7, // Valid only on an interface | ||
#else | ||
kLinkLocal = 3, // Valid only on an interface | ||
kUniqueLocal = 4, // ULA. Thread devices use this | ||
kGlobalUnicast = 5, // Maybe routable, not local subnet | ||
kUniqueLocalWithSharedPrefix = 6, // Prefix seems to match a local interface | ||
kGlobalUnicastWithSharedPrefix = 7, // Prefix seems to match a local interface | ||
#endif // __APPLE__ | ||
}; | ||
|
||
class IPAddressSorter | ||
{ | ||
public: | ||
static void Sort(Inet::IPAddress * addresses, size_t count, Inet::InterfaceId interfaceId); | ||
static void Sort(const Span<Inet::IPAddress> & addresses, Inet::InterfaceId interfaceId); | ||
|
||
/** | ||
* Gives a score for an IP address, generally related to "how good" the address | ||
* is and how likely it is for it to be reachable. | ||
*/ | ||
static IpScore ScoreIpAddress(const Inet::IPAddress & ip, Inet::InterfaceId interfaceId); | ||
|
||
private: | ||
IPAddressSorter(); | ||
}; | ||
|
||
} // namespace Dnssd | ||
} // namespace chip |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters