candidate.h (11269B)
1 /* 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #ifndef API_CANDIDATE_H_ 12 #define API_CANDIDATE_H_ 13 14 #include <stddef.h> 15 #include <stdint.h> 16 17 #include <string> 18 19 #include "absl/strings/string_view.h" 20 #include "rtc_base/checks.h" 21 #include "rtc_base/network_constants.h" 22 #include "rtc_base/socket_address.h" 23 #include "rtc_base/system/rtc_export.h" 24 25 namespace webrtc { 26 27 enum class IceCandidateType : int { kHost, kSrflx, kPrflx, kRelay }; 28 RTC_EXPORT absl::string_view IceCandidateTypeToString(IceCandidateType); 29 30 // TODO(tommi): Remove. No usage in WebRTC now, remove once downstream projects 31 // don't have reliance. 32 [[deprecated("Use IceCandidateType")]] static constexpr char LOCAL_PORT_TYPE[] = 33 "local"; 34 [[deprecated("Use IceCandidateType")]] static constexpr char STUN_PORT_TYPE[] = 35 "stun"; 36 [[deprecated("Use IceCandidateType")]] static constexpr char PRFLX_PORT_TYPE[] = 37 "prflx"; 38 [[deprecated("Use IceCandidateType")]] static constexpr char RELAY_PORT_TYPE[] = 39 "relay"; 40 41 // TURN servers are limited to 32 in accordance with 42 // https://w3c.github.io/webrtc-pc/#dom-rtcconfiguration-iceservers 43 static constexpr size_t kMaxTurnServers = 32; 44 45 // Candidate for ICE based connection discovery. 46 class RTC_EXPORT Candidate { 47 public: 48 Candidate(); 49 Candidate(int component, 50 absl::string_view protocol, 51 const SocketAddress& address, 52 uint32_t priority, 53 absl::string_view username, 54 absl::string_view password, 55 IceCandidateType type, 56 uint32_t generation, 57 absl::string_view foundation, 58 uint16_t network_id = 0, 59 uint16_t network_cost = 0); 60 Candidate(const Candidate&); 61 ~Candidate(); 62 63 // 8 character long randomized ID string for logging purposes. 64 const std::string& id() const { return id_; } 65 // Generates a new, 8 character long, id. 66 void generate_id(); 67 68 int component() const { return component_; } 69 void set_component(int component) { component_ = component; } 70 71 const std::string& protocol() const { return protocol_; } 72 73 // Valid protocol values are: 74 // UDP_PROTOCOL_NAME, TCP_PROTOCOL_NAME, SSLTCP_PROTOCOL_NAME, 75 // TLS_PROTOCOL_NAME. 76 void set_protocol(absl::string_view protocol) { Assign(protocol_, protocol); } 77 78 // The protocol used to talk to relay. 79 const std::string& relay_protocol() const { return relay_protocol_; } 80 81 // Valid protocol values are: 82 // UDP_PROTOCOL_NAME, TCP_PROTOCOL_NAME, SSLTCP_PROTOCOL_NAME, 83 // TLS_PROTOCOL_NAME. 84 void set_relay_protocol(absl::string_view protocol) { 85 Assign(relay_protocol_, protocol); 86 } 87 88 const SocketAddress& address() const { return address_; } 89 void set_address(const SocketAddress& address) { address_ = address; } 90 91 uint32_t priority() const { return priority_; } 92 void set_priority(const uint32_t priority) { priority_ = priority; } 93 94 // TODO(honghaiz): Change to usernameFragment or ufrag. 95 const std::string& username() const { return username_; } 96 void set_username(absl::string_view username) { Assign(username_, username); } 97 98 const std::string& password() const { return password_; } 99 void set_password(absl::string_view password) { Assign(password_, password); } 100 101 IceCandidateType type() const { return type_; } 102 103 // Returns the name of the candidate type as specified in 104 // https://datatracker.ietf.org/doc/html/rfc5245#section-15.1 105 absl::string_view type_name() const; 106 107 // Setting the type requires a constant string (e.g. 108 // LOCAL_PORT_TYPE). The type should really be an enum rather than a 109 // string, but until we make that change the lifetime attribute helps us lock 110 // things down. See also the `Port` class. 111 void set_type(IceCandidateType type) { type_ = type; } 112 113 // Simple checkers for checking the candidate type without dependency on the 114 // IceCandidateType enum. The `is_local()` and `is_stun()` names are legacy 115 // names and should now more accurately be `is_host()` and `is_srflx()`. 116 bool is_local() const; 117 bool is_stun() const; 118 bool is_prflx() const; 119 bool is_relay() const; 120 121 // Returns the type preference, a value between 0-126 inclusive, with 0 being 122 // the lowest preference value, as described in RFC 5245. 123 // https://datatracker.ietf.org/doc/html/rfc5245#section-4.1.2.1 124 int type_preference() const { 125 // From https://datatracker.ietf.org/doc/html/rfc5245#section-4.1.4 : 126 // It is RECOMMENDED that default candidates be chosen based on the 127 // likelihood of those candidates to work with the peer that is being 128 // contacted. 129 // I.e. it is recommended that relayed > reflexive > host. 130 if (is_local()) 131 return 1; // Host. 132 if (is_stun()) 133 return 2; // Reflexive. 134 if (is_relay()) 135 return 3; // Relayed. 136 return 0; // Unknown, lowest preference. 137 } 138 139 const std::string& network_name() const { return network_name_; } 140 void set_network_name(absl::string_view network_name) { 141 Assign(network_name_, network_name); 142 } 143 144 AdapterType network_type() const { return network_type_; } 145 void set_network_type(AdapterType network_type) { 146 network_type_ = network_type; 147 } 148 149 AdapterType underlying_type_for_vpn() const { 150 return underlying_type_for_vpn_; 151 } 152 void set_underlying_type_for_vpn(AdapterType network_type) { 153 underlying_type_for_vpn_ = network_type; 154 } 155 156 // Candidates in a new generation replace those in the old generation. 157 uint32_t generation() const { return generation_; } 158 void set_generation(uint32_t generation) { generation_ = generation; } 159 160 // `network_cost` measures the cost/penalty of using this candidate. A network 161 // cost of 0 indicates this candidate can be used freely. A value of 162 // kNetworkCostMax indicates it should be used only as the last 163 // resort. 164 void set_network_cost(uint16_t network_cost) { 165 RTC_DCHECK_LE(network_cost, kNetworkCostMax); 166 network_cost_ = network_cost; 167 } 168 uint16_t network_cost() const { return network_cost_; } 169 170 // An ID assigned to the network hosting the candidate. 171 uint16_t network_id() const { return network_id_; } 172 void set_network_id(uint16_t network_id) { network_id_ = network_id; } 173 174 // From RFC 5245, section-7.2.1.3: 175 // The foundation of the candidate is set to an arbitrary value, different 176 // from the foundation for all other remote candidates. 177 // Note: Use ComputeFoundation to populate this value. 178 const std::string& foundation() const { return foundation_; } 179 180 // TODO(tommi): Deprecate in favor of ComputeFoundation. 181 // For situations where serializing/deserializing a candidate is needed, 182 // the constructor can be used to inject a value for the foundation. 183 void set_foundation(absl::string_view foundation) { 184 Assign(foundation_, foundation); 185 } 186 187 const SocketAddress& related_address() const { return related_address_; } 188 void set_related_address(const SocketAddress& related_address) { 189 related_address_ = related_address; 190 } 191 const std::string& tcptype() const { return tcptype_; } 192 void set_tcptype(absl::string_view tcptype) { Assign(tcptype_, tcptype); } 193 194 // The URL of the ICE server which this candidate is gathered from. 195 const std::string& url() const { return url_; } 196 void set_url(absl::string_view url) { Assign(url_, url); } 197 198 // Determines whether this candidate is equivalent to the given one. 199 bool IsEquivalent(const Candidate& c) const; 200 201 // Determines whether this candidate can be considered equivalent to the 202 // given one when looking for a matching candidate to remove. 203 bool MatchesForRemoval(const Candidate& c) const; 204 205 std::string ToString() const { return ToStringInternal(false); } 206 207 std::string ToSensitiveString() const { return ToStringInternal(true); } 208 209 uint32_t GetPriority(uint32_t type_preference, 210 int network_adapter_preference, 211 int relay_preference, 212 bool adjust_local_preference) const; 213 214 bool operator==(const Candidate& o) const; 215 bool operator!=(const Candidate& o) const; 216 217 // Returns a sanitized copy configured by the given booleans. If 218 // `use_host_address` is true, the returned copy has its IP removed from 219 // `address()`, which leads `address()` to be a hostname address. If 220 // `filter_related_address`, the returned copy has its related address reset 221 // to the wildcard address (i.e. 0.0.0.0 for IPv4 and :: for IPv6). Note that 222 // setting both booleans to false returns an identical copy to the original 223 // candidate. 224 // The username fragment may be filtered, e.g. for prflx candidates before 225 // any remote ice parameters have been set. 226 [[deprecated("Use variant with filter_ufrag")]] Candidate ToSanitizedCopy( 227 bool use_hostname_address, 228 bool filter_related_address) const; 229 Candidate ToSanitizedCopy(bool use_hostname_address, 230 bool filter_related_address, 231 bool filter_ufrag) const; 232 233 // Computes and populates the `foundation()` field. 234 // Foundation: An arbitrary string that is the same for two candidates 235 // that have the same type, base IP address, protocol (UDP, TCP, 236 // etc.), and STUN or TURN server. If any of these are different, 237 // then the foundation will be different. Two candidate pairs with 238 // the same foundation pairs are likely to have similar network 239 // characteristics. Foundations are used in the frozen algorithm. 240 // A session wide (peerconnection) tie-breaker is applied to the foundation, 241 // adds additional randomness and must be the same for all candidates. 242 void ComputeFoundation(const SocketAddress& base_address, 243 uint64_t tie_breaker); 244 245 // https://www.rfc-editor.org/rfc/rfc5245#section-7.2.1.3 246 // Call to populate the foundation field for a new peer reflexive remote 247 // candidate. The type of the candidate must be "prflx". 248 // The foundation of the candidate is set to an arbitrary value, different 249 // from the foundation for all other remote candidates. 250 void ComputePrflxFoundation(); 251 252 private: 253 // TODO(bugs.webrtc.org/13220): With C++17, we get a std::string assignment 254 // operator accepting any object implicitly convertible to std::string_view, 255 // and then we don't need this workaround. 256 static void Assign(std::string& s, absl::string_view view); 257 std::string ToStringInternal(bool sensitive) const; 258 259 std::string id_; 260 int component_; 261 std::string protocol_; 262 std::string relay_protocol_; 263 SocketAddress address_; 264 uint32_t priority_; 265 std::string username_; 266 std::string password_; 267 IceCandidateType type_ = IceCandidateType::kHost; 268 std::string network_name_; 269 AdapterType network_type_; 270 AdapterType underlying_type_for_vpn_; 271 uint32_t generation_; 272 std::string foundation_; 273 SocketAddress related_address_; 274 std::string tcptype_; 275 uint16_t network_id_; 276 uint16_t network_cost_; 277 std::string url_; 278 }; 279 280 } // namespace webrtc 281 282 283 #endif // API_CANDIDATE_H_