xref: /aosp_15_r20/external/webrtc/api/candidate.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright 2017 The WebRTC Project Authors. All rights reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker #include "api/candidate.h"
12*d9f75844SAndroid Build Coastguard Worker 
13*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/helpers.h"
14*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/ip_address.h"
15*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/logging.h"
16*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/strings/string_builder.h"
17*d9f75844SAndroid Build Coastguard Worker 
18*d9f75844SAndroid Build Coastguard Worker namespace cricket {
19*d9f75844SAndroid Build Coastguard Worker 
Candidate()20*d9f75844SAndroid Build Coastguard Worker Candidate::Candidate()
21*d9f75844SAndroid Build Coastguard Worker     : id_(rtc::CreateRandomString(8)),
22*d9f75844SAndroid Build Coastguard Worker       component_(0),
23*d9f75844SAndroid Build Coastguard Worker       priority_(0),
24*d9f75844SAndroid Build Coastguard Worker       network_type_(rtc::ADAPTER_TYPE_UNKNOWN),
25*d9f75844SAndroid Build Coastguard Worker       underlying_type_for_vpn_(rtc::ADAPTER_TYPE_UNKNOWN),
26*d9f75844SAndroid Build Coastguard Worker       generation_(0),
27*d9f75844SAndroid Build Coastguard Worker       network_id_(0),
28*d9f75844SAndroid Build Coastguard Worker       network_cost_(0) {}
29*d9f75844SAndroid Build Coastguard Worker 
Candidate(int component,absl::string_view protocol,const rtc::SocketAddress & address,uint32_t priority,absl::string_view username,absl::string_view password,absl::string_view type,uint32_t generation,absl::string_view foundation,uint16_t network_id,uint16_t network_cost)30*d9f75844SAndroid Build Coastguard Worker Candidate::Candidate(int component,
31*d9f75844SAndroid Build Coastguard Worker                      absl::string_view protocol,
32*d9f75844SAndroid Build Coastguard Worker                      const rtc::SocketAddress& address,
33*d9f75844SAndroid Build Coastguard Worker                      uint32_t priority,
34*d9f75844SAndroid Build Coastguard Worker                      absl::string_view username,
35*d9f75844SAndroid Build Coastguard Worker                      absl::string_view password,
36*d9f75844SAndroid Build Coastguard Worker                      absl::string_view type,
37*d9f75844SAndroid Build Coastguard Worker                      uint32_t generation,
38*d9f75844SAndroid Build Coastguard Worker                      absl::string_view foundation,
39*d9f75844SAndroid Build Coastguard Worker                      uint16_t network_id,
40*d9f75844SAndroid Build Coastguard Worker                      uint16_t network_cost)
41*d9f75844SAndroid Build Coastguard Worker     : id_(rtc::CreateRandomString(8)),
42*d9f75844SAndroid Build Coastguard Worker       component_(component),
43*d9f75844SAndroid Build Coastguard Worker       protocol_(protocol),
44*d9f75844SAndroid Build Coastguard Worker       address_(address),
45*d9f75844SAndroid Build Coastguard Worker       priority_(priority),
46*d9f75844SAndroid Build Coastguard Worker       username_(username),
47*d9f75844SAndroid Build Coastguard Worker       password_(password),
48*d9f75844SAndroid Build Coastguard Worker       type_(type),
49*d9f75844SAndroid Build Coastguard Worker       network_type_(rtc::ADAPTER_TYPE_UNKNOWN),
50*d9f75844SAndroid Build Coastguard Worker       underlying_type_for_vpn_(rtc::ADAPTER_TYPE_UNKNOWN),
51*d9f75844SAndroid Build Coastguard Worker       generation_(generation),
52*d9f75844SAndroid Build Coastguard Worker       foundation_(foundation),
53*d9f75844SAndroid Build Coastguard Worker       network_id_(network_id),
54*d9f75844SAndroid Build Coastguard Worker       network_cost_(network_cost) {}
55*d9f75844SAndroid Build Coastguard Worker 
56*d9f75844SAndroid Build Coastguard Worker Candidate::Candidate(const Candidate&) = default;
57*d9f75844SAndroid Build Coastguard Worker 
58*d9f75844SAndroid Build Coastguard Worker Candidate::~Candidate() = default;
59*d9f75844SAndroid Build Coastguard Worker 
IsEquivalent(const Candidate & c) const60*d9f75844SAndroid Build Coastguard Worker bool Candidate::IsEquivalent(const Candidate& c) const {
61*d9f75844SAndroid Build Coastguard Worker   // We ignore the network name, since that is just debug information, and
62*d9f75844SAndroid Build Coastguard Worker   // the priority and the network cost, since they should be the same if the
63*d9f75844SAndroid Build Coastguard Worker   // rest are.
64*d9f75844SAndroid Build Coastguard Worker   return (component_ == c.component_) && (protocol_ == c.protocol_) &&
65*d9f75844SAndroid Build Coastguard Worker          (address_ == c.address_) && (username_ == c.username_) &&
66*d9f75844SAndroid Build Coastguard Worker          (password_ == c.password_) && (type_ == c.type_) &&
67*d9f75844SAndroid Build Coastguard Worker          (generation_ == c.generation_) && (foundation_ == c.foundation_) &&
68*d9f75844SAndroid Build Coastguard Worker          (related_address_ == c.related_address_) &&
69*d9f75844SAndroid Build Coastguard Worker          (network_id_ == c.network_id_);
70*d9f75844SAndroid Build Coastguard Worker }
71*d9f75844SAndroid Build Coastguard Worker 
MatchesForRemoval(const Candidate & c) const72*d9f75844SAndroid Build Coastguard Worker bool Candidate::MatchesForRemoval(const Candidate& c) const {
73*d9f75844SAndroid Build Coastguard Worker   return component_ == c.component_ && protocol_ == c.protocol_ &&
74*d9f75844SAndroid Build Coastguard Worker          address_ == c.address_;
75*d9f75844SAndroid Build Coastguard Worker }
76*d9f75844SAndroid Build Coastguard Worker 
ToStringInternal(bool sensitive) const77*d9f75844SAndroid Build Coastguard Worker std::string Candidate::ToStringInternal(bool sensitive) const {
78*d9f75844SAndroid Build Coastguard Worker   rtc::StringBuilder ost;
79*d9f75844SAndroid Build Coastguard Worker   std::string address =
80*d9f75844SAndroid Build Coastguard Worker       sensitive ? address_.ToSensitiveString() : address_.ToString();
81*d9f75844SAndroid Build Coastguard Worker   ost << "Cand[" << transport_name_ << ":" << foundation_ << ":" << component_
82*d9f75844SAndroid Build Coastguard Worker       << ":" << protocol_ << ":" << priority_ << ":" << address << ":" << type_
83*d9f75844SAndroid Build Coastguard Worker       << ":" << related_address_.ToString() << ":" << username_ << ":"
84*d9f75844SAndroid Build Coastguard Worker       << password_ << ":" << network_id_ << ":" << network_cost_ << ":"
85*d9f75844SAndroid Build Coastguard Worker       << generation_ << "]";
86*d9f75844SAndroid Build Coastguard Worker   return ost.Release();
87*d9f75844SAndroid Build Coastguard Worker }
88*d9f75844SAndroid Build Coastguard Worker 
GetPriority(uint32_t type_preference,int network_adapter_preference,int relay_preference) const89*d9f75844SAndroid Build Coastguard Worker uint32_t Candidate::GetPriority(uint32_t type_preference,
90*d9f75844SAndroid Build Coastguard Worker                                 int network_adapter_preference,
91*d9f75844SAndroid Build Coastguard Worker                                 int relay_preference) const {
92*d9f75844SAndroid Build Coastguard Worker   // RFC 5245 - 4.1.2.1.
93*d9f75844SAndroid Build Coastguard Worker   // priority = (2^24)*(type preference) +
94*d9f75844SAndroid Build Coastguard Worker   //            (2^8)*(local preference) +
95*d9f75844SAndroid Build Coastguard Worker   //            (2^0)*(256 - component ID)
96*d9f75844SAndroid Build Coastguard Worker 
97*d9f75844SAndroid Build Coastguard Worker   // `local_preference` length is 2 bytes, 0-65535 inclusive.
98*d9f75844SAndroid Build Coastguard Worker   // In our implemenation we will partion local_preference into
99*d9f75844SAndroid Build Coastguard Worker   //              0                 1
100*d9f75844SAndroid Build Coastguard Worker   //       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
101*d9f75844SAndroid Build Coastguard Worker   //      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
102*d9f75844SAndroid Build Coastguard Worker   //      |  NIC Pref     |    Addr Pref  |
103*d9f75844SAndroid Build Coastguard Worker   //      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
104*d9f75844SAndroid Build Coastguard Worker   // NIC Type - Type of the network adapter e.g. 3G/Wifi/Wired.
105*d9f75844SAndroid Build Coastguard Worker   // Addr Pref - Address preference value as per RFC 3484.
106*d9f75844SAndroid Build Coastguard Worker   // local preference =  (NIC Type << 8 | Addr_Pref) + relay preference.
107*d9f75844SAndroid Build Coastguard Worker   // The relay preference is based on the number of TURN servers, the
108*d9f75844SAndroid Build Coastguard Worker   // first TURN server gets the highest preference.
109*d9f75844SAndroid Build Coastguard Worker 
110*d9f75844SAndroid Build Coastguard Worker   int addr_pref = IPAddressPrecedence(address_.ipaddr());
111*d9f75844SAndroid Build Coastguard Worker   int local_preference =
112*d9f75844SAndroid Build Coastguard Worker       ((network_adapter_preference << 8) | addr_pref) + relay_preference;
113*d9f75844SAndroid Build Coastguard Worker 
114*d9f75844SAndroid Build Coastguard Worker   return (type_preference << 24) | (local_preference << 8) | (256 - component_);
115*d9f75844SAndroid Build Coastguard Worker }
116*d9f75844SAndroid Build Coastguard Worker 
operator ==(const Candidate & o) const117*d9f75844SAndroid Build Coastguard Worker bool Candidate::operator==(const Candidate& o) const {
118*d9f75844SAndroid Build Coastguard Worker   return id_ == o.id_ && component_ == o.component_ &&
119*d9f75844SAndroid Build Coastguard Worker          protocol_ == o.protocol_ && relay_protocol_ == o.relay_protocol_ &&
120*d9f75844SAndroid Build Coastguard Worker          address_ == o.address_ && priority_ == o.priority_ &&
121*d9f75844SAndroid Build Coastguard Worker          username_ == o.username_ && password_ == o.password_ &&
122*d9f75844SAndroid Build Coastguard Worker          type_ == o.type_ && network_name_ == o.network_name_ &&
123*d9f75844SAndroid Build Coastguard Worker          network_type_ == o.network_type_ && generation_ == o.generation_ &&
124*d9f75844SAndroid Build Coastguard Worker          foundation_ == o.foundation_ &&
125*d9f75844SAndroid Build Coastguard Worker          related_address_ == o.related_address_ && tcptype_ == o.tcptype_ &&
126*d9f75844SAndroid Build Coastguard Worker          transport_name_ == o.transport_name_ && network_id_ == o.network_id_;
127*d9f75844SAndroid Build Coastguard Worker }
128*d9f75844SAndroid Build Coastguard Worker 
operator !=(const Candidate & o) const129*d9f75844SAndroid Build Coastguard Worker bool Candidate::operator!=(const Candidate& o) const {
130*d9f75844SAndroid Build Coastguard Worker   return !(*this == o);
131*d9f75844SAndroid Build Coastguard Worker }
132*d9f75844SAndroid Build Coastguard Worker 
ToSanitizedCopy(bool use_hostname_address,bool filter_related_address) const133*d9f75844SAndroid Build Coastguard Worker Candidate Candidate::ToSanitizedCopy(bool use_hostname_address,
134*d9f75844SAndroid Build Coastguard Worker                                      bool filter_related_address) const {
135*d9f75844SAndroid Build Coastguard Worker   Candidate copy(*this);
136*d9f75844SAndroid Build Coastguard Worker   if (use_hostname_address) {
137*d9f75844SAndroid Build Coastguard Worker     rtc::IPAddress ip;
138*d9f75844SAndroid Build Coastguard Worker     if (address().hostname().empty()) {
139*d9f75844SAndroid Build Coastguard Worker       // IP needs to be redacted, but no hostname available.
140*d9f75844SAndroid Build Coastguard Worker       rtc::SocketAddress redacted_addr("redacted-ip.invalid", address().port());
141*d9f75844SAndroid Build Coastguard Worker       copy.set_address(redacted_addr);
142*d9f75844SAndroid Build Coastguard Worker     } else if (IPFromString(address().hostname(), &ip)) {
143*d9f75844SAndroid Build Coastguard Worker       // The hostname is an IP literal, and needs to be redacted too.
144*d9f75844SAndroid Build Coastguard Worker       rtc::SocketAddress redacted_addr("redacted-literal.invalid",
145*d9f75844SAndroid Build Coastguard Worker                                        address().port());
146*d9f75844SAndroid Build Coastguard Worker       copy.set_address(redacted_addr);
147*d9f75844SAndroid Build Coastguard Worker     } else {
148*d9f75844SAndroid Build Coastguard Worker       rtc::SocketAddress hostname_only_addr(address().hostname(),
149*d9f75844SAndroid Build Coastguard Worker                                             address().port());
150*d9f75844SAndroid Build Coastguard Worker       copy.set_address(hostname_only_addr);
151*d9f75844SAndroid Build Coastguard Worker     }
152*d9f75844SAndroid Build Coastguard Worker   }
153*d9f75844SAndroid Build Coastguard Worker   if (filter_related_address) {
154*d9f75844SAndroid Build Coastguard Worker     copy.set_related_address(
155*d9f75844SAndroid Build Coastguard Worker         rtc::EmptySocketAddressWithFamily(copy.address().family()));
156*d9f75844SAndroid Build Coastguard Worker   }
157*d9f75844SAndroid Build Coastguard Worker   return copy;
158*d9f75844SAndroid Build Coastguard Worker }
159*d9f75844SAndroid Build Coastguard Worker 
Assign(std::string & s,absl::string_view view)160*d9f75844SAndroid Build Coastguard Worker void Candidate::Assign(std::string& s, absl::string_view view) {
161*d9f75844SAndroid Build Coastguard Worker   // Assigning via a temporary object, like s = std::string(view), results in
162*d9f75844SAndroid Build Coastguard Worker   // binary size bloat. To avoid that, extract pointer and size from the
163*d9f75844SAndroid Build Coastguard Worker   // string view, and use std::string::assign method.
164*d9f75844SAndroid Build Coastguard Worker   s.assign(view.data(), view.size());
165*d9f75844SAndroid Build Coastguard Worker }
166*d9f75844SAndroid Build Coastguard Worker 
167*d9f75844SAndroid Build Coastguard Worker }  // namespace cricket
168