blob: 95359620c40285dc5cb93ba7a1232e19d3b62363 [file] [log] [blame]
Patrik Höglunde2d6a062017-10-05 12:53:331/*
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 <limits.h>
15#include <stdint.h>
16
17#include <algorithm>
18#include <string>
19
Tommi6bf2d312023-09-25 12:05:3120#include "absl/base/attributes.h"
Niels Möllerd4aa3a32021-09-29 11:23:0121#include "absl/strings/string_view.h"
Patrik Höglunde2d6a062017-10-05 12:53:3322#include "rtc_base/checks.h"
Patrik Höglunde2d6a062017-10-05 12:53:3323#include "rtc_base/network_constants.h"
Steve Anton10542f22019-01-11 17:11:0024#include "rtc_base/socket_address.h"
Mirko Bonadei3b56ee72018-10-15 15:15:1225#include "rtc_base/system/rtc_export.h"
Patrik Höglunde2d6a062017-10-05 12:53:3326
Tommi32f2a302024-02-08 18:16:4927namespace webrtc {
28enum class IceCandidateType : int { kHost, kSrflx, kPrflx, kRelay };
Tommic7a4b2a2024-02-25 22:34:3929RTC_EXPORT absl::string_view IceCandidateTypeToString(IceCandidateType);
Tommi32f2a302024-02-08 18:16:4930} // namespace webrtc
31
Patrik Höglunde2d6a062017-10-05 12:53:3332namespace cricket {
33
Tommi3b2b2af2024-01-17 13:19:4134// TODO(tommi): These are temporarily here, moved from `port.h` and will
35// eventually be removed once we use enums instead of strings for these values.
Tommi521b8632024-02-12 13:52:1336RTC_EXPORT extern const absl::string_view LOCAL_PORT_TYPE;
37RTC_EXPORT extern const absl::string_view STUN_PORT_TYPE;
38RTC_EXPORT extern const absl::string_view PRFLX_PORT_TYPE;
39RTC_EXPORT extern const absl::string_view RELAY_PORT_TYPE;
Tommi3b2b2af2024-01-17 13:19:4140
Philipp Hancke41a83572022-11-28 13:47:4541// TURN servers are limited to 32 in accordance with
42// https://w3c.github.io/webrtc-pc/#dom-rtcconfiguration-iceservers
43static constexpr size_t kMaxTurnServers = 32;
44
Patrik Höglunde2d6a062017-10-05 12:53:3345// Candidate for ICE based connection discovery.
Mirko Bonadei3b56ee72018-10-15 15:15:1246class RTC_EXPORT Candidate {
Patrik Höglunde2d6a062017-10-05 12:53:3347 public:
Steve Anton36b28db2017-10-26 18:27:1748 Candidate();
Tommic7a4b2a2024-02-25 22:34:3949 Candidate(int component,
50 absl::string_view protocol,
51 const rtc::SocketAddress& address,
52 uint32_t priority,
53 absl::string_view username,
54 absl::string_view password,
55 webrtc::IceCandidateType type,
56 uint32_t generation,
57 absl::string_view foundation,
58 uint16_t network_id = 0,
59 uint16_t network_cost = 0);
60 // TODO(tommi): Deprecate.
Patrik Höglunde2d6a062017-10-05 12:53:3361 Candidate(int component,
Niels Möllerd4aa3a32021-09-29 11:23:0162 absl::string_view protocol,
Patrik Höglunde2d6a062017-10-05 12:53:3363 const rtc::SocketAddress& address,
64 uint32_t priority,
Niels Möllerd4aa3a32021-09-29 11:23:0165 absl::string_view username,
66 absl::string_view password,
Tommi6bf2d312023-09-25 12:05:3167 absl::string_view type ABSL_ATTRIBUTE_LIFETIME_BOUND,
Patrik Höglunde2d6a062017-10-05 12:53:3368 uint32_t generation,
Niels Möllerd4aa3a32021-09-29 11:23:0169 absl::string_view foundation,
Patrik Höglunde2d6a062017-10-05 12:53:3370 uint16_t network_id = 0,
Steve Anton36b28db2017-10-26 18:27:1771 uint16_t network_cost = 0);
72 Candidate(const Candidate&);
73 ~Candidate();
Patrik Höglunde2d6a062017-10-05 12:53:3374
Tommibde80e32024-02-17 14:52:5775 // 8 character long randomized ID string for logging purposes.
Yves Gerey665174f2018-06-19 13:03:0576 const std::string& id() const { return id_; }
Tommibde80e32024-02-17 14:52:5777 // Generates a new, 8 character long, id.
78 void generate_id();
79 // TODO(tommi): Callers should use generate_id(). Remove.
80 [[deprecated]] void set_id(absl::string_view id) { Assign(id_, id); }
Patrik Höglunde2d6a062017-10-05 12:53:3381
82 int component() const { return component_; }
83 void set_component(int component) { component_ = component; }
84
Yves Gerey665174f2018-06-19 13:03:0585 const std::string& protocol() const { return protocol_; }
Tommif2431a92024-02-20 14:27:4486
87 // Valid protocol values are:
88 // UDP_PROTOCOL_NAME, TCP_PROTOCOL_NAME, SSLTCP_PROTOCOL_NAME,
89 // TLS_PROTOCOL_NAME.
Niels Möllerd4aa3a32021-09-29 11:23:0190 void set_protocol(absl::string_view protocol) { Assign(protocol_, protocol); }
Patrik Höglunde2d6a062017-10-05 12:53:3391
92 // The protocol used to talk to relay.
93 const std::string& relay_protocol() const { return relay_protocol_; }
Tommif2431a92024-02-20 14:27:4494
95 // Valid protocol values are:
96 // UDP_PROTOCOL_NAME, TCP_PROTOCOL_NAME, SSLTCP_PROTOCOL_NAME,
97 // TLS_PROTOCOL_NAME.
Niels Möllerd4aa3a32021-09-29 11:23:0198 void set_relay_protocol(absl::string_view protocol) {
99 Assign(relay_protocol_, protocol);
Patrik Höglunde2d6a062017-10-05 12:53:33100 }
101
Yves Gerey665174f2018-06-19 13:03:05102 const rtc::SocketAddress& address() const { return address_; }
103 void set_address(const rtc::SocketAddress& address) { address_ = address; }
Patrik Höglunde2d6a062017-10-05 12:53:33104
105 uint32_t priority() const { return priority_; }
106 void set_priority(const uint32_t priority) { priority_ = priority; }
107
Patrik Höglunde2d6a062017-10-05 12:53:33108 // TODO(honghaiz): Change to usernameFragment or ufrag.
Yves Gerey665174f2018-06-19 13:03:05109 const std::string& username() const { return username_; }
Niels Möllerd4aa3a32021-09-29 11:23:01110 void set_username(absl::string_view username) { Assign(username_, username); }
Patrik Höglunde2d6a062017-10-05 12:53:33111
Yves Gerey665174f2018-06-19 13:03:05112 const std::string& password() const { return password_; }
Niels Möllerd4aa3a32021-09-29 11:23:01113 void set_password(absl::string_view password) { Assign(password_, password); }
Patrik Höglunde2d6a062017-10-05 12:53:33114
Tommic7a4b2a2024-02-25 22:34:39115 webrtc::IceCandidateType type() const { return type_; }
Tommi6bf2d312023-09-25 12:05:31116
Tommif7b22c62024-02-15 08:18:34117 // Returns the name of the candidate type as specified in
118 // https://datatracker.ietf.org/doc/html/rfc5245#section-15.1
119 absl::string_view type_name() const;
120
Tommi6bf2d312023-09-25 12:05:31121 // Setting the type requires a constant string (e.g.
122 // cricket::LOCAL_PORT_TYPE). The type should really be an enum rather than a
123 // string, but until we make that change the lifetime attribute helps us lock
124 // things down. See also the `Port` class.
Tommic7a4b2a2024-02-25 22:34:39125 void set_type(webrtc::IceCandidateType type) { type_ = type; }
Patrik Höglunde2d6a062017-10-05 12:53:33126
Tommic7a4b2a2024-02-25 22:34:39127 // TODO(tommi): Deprecate.
128 void set_type(absl::string_view type ABSL_ATTRIBUTE_LIFETIME_BOUND);
129
130 // Simple checkers for checking the candidate type without dependency on the
131 // IceCandidateType enum. The `is_local()` and `is_stun()` names are legacy
132 // names and should now more accurately be `is_host()` and `is_srflx()`.
Tommi3b2b2af2024-01-17 13:19:41133 bool is_local() const;
134 bool is_stun() const;
135 bool is_prflx() const;
136 bool is_relay() const;
137
Tommibe2786c2024-01-19 16:33:00138 // Returns the type preference, a value between 0-126 inclusive, with 0 being
139 // the lowest preference value, as described in RFC 5245.
140 // https://datatracker.ietf.org/doc/html/rfc5245#section-4.1.2.1
141 int type_preference() const {
142 // From https://datatracker.ietf.org/doc/html/rfc5245#section-4.1.4 :
143 // It is RECOMMENDED that default candidates be chosen based on the
144 // likelihood of those candidates to work with the peer that is being
145 // contacted.
146 // I.e. it is recommended that relayed > reflexive > host.
147 if (is_local())
148 return 1; // Host.
149 if (is_stun())
150 return 2; // Reflexive.
151 if (is_relay())
152 return 3; // Relayed.
153 return 0; // Unknown, lowest preference.
154 }
155
Yves Gerey665174f2018-06-19 13:03:05156 const std::string& network_name() const { return network_name_; }
Niels Möllerd4aa3a32021-09-29 11:23:01157 void set_network_name(absl::string_view network_name) {
158 Assign(network_name_, network_name);
Patrik Höglunde2d6a062017-10-05 12:53:33159 }
160
161 rtc::AdapterType network_type() const { return network_type_; }
162 void set_network_type(rtc::AdapterType network_type) {
163 network_type_ = network_type;
164 }
165
Jonas Oreland0d13bbd2022-03-02 10:17:36166 rtc::AdapterType underlying_type_for_vpn() const {
167 return underlying_type_for_vpn_;
168 }
169 void set_underlying_type_for_vpn(rtc::AdapterType network_type) {
170 underlying_type_for_vpn_ = network_type;
171 }
172
Patrik Höglunde2d6a062017-10-05 12:53:33173 // Candidates in a new generation replace those in the old generation.
174 uint32_t generation() const { return generation_; }
175 void set_generation(uint32_t generation) { generation_ = generation; }
Patrik Höglunde2d6a062017-10-05 12:53:33176
Artem Titov0e61fdd2021-07-25 19:50:14177 // `network_cost` measures the cost/penalty of using this candidate. A network
Patrik Höglunde2d6a062017-10-05 12:53:33178 // cost of 0 indicates this candidate can be used freely. A value of
179 // rtc::kNetworkCostMax indicates it should be used only as the last resort.
180 void set_network_cost(uint16_t network_cost) {
181 RTC_DCHECK_LE(network_cost, rtc::kNetworkCostMax);
182 network_cost_ = network_cost;
183 }
184 uint16_t network_cost() const { return network_cost_; }
185
186 // An ID assigned to the network hosting the candidate.
187 uint16_t network_id() const { return network_id_; }
188 void set_network_id(uint16_t network_id) { network_id_ = network_id; }
189
Tommif2431a92024-02-20 14:27:44190 // From RFC 5245, section-7.2.1.3:
191 // The foundation of the candidate is set to an arbitrary value, different
192 // from the foundation for all other remote candidates.
193 // Note: Use ComputeFoundation to populate this value.
Yves Gerey665174f2018-06-19 13:03:05194 const std::string& foundation() const { return foundation_; }
Tommif2431a92024-02-20 14:27:44195
196 // TODO(tommi): Deprecate in favor of ComputeFoundation.
197 // For situations where serializing/deserializing a candidate is needed,
198 // the constructor can be used to inject a value for the foundation.
Niels Möllerd4aa3a32021-09-29 11:23:01199 void set_foundation(absl::string_view foundation) {
200 Assign(foundation_, foundation);
Patrik Höglunde2d6a062017-10-05 12:53:33201 }
202
Yves Gerey665174f2018-06-19 13:03:05203 const rtc::SocketAddress& related_address() const { return related_address_; }
204 void set_related_address(const rtc::SocketAddress& related_address) {
Patrik Höglunde2d6a062017-10-05 12:53:33205 related_address_ = related_address;
206 }
207 const std::string& tcptype() const { return tcptype_; }
Niels Möllerd4aa3a32021-09-29 11:23:01208 void set_tcptype(absl::string_view tcptype) { Assign(tcptype_, tcptype); }
Patrik Höglunde2d6a062017-10-05 12:53:33209
210 // The name of the transport channel of this candidate.
211 // TODO(phoglund): remove.
212 const std::string& transport_name() const { return transport_name_; }
Niels Möllerd4aa3a32021-09-29 11:23:01213 void set_transport_name(absl::string_view transport_name) {
214 Assign(transport_name_, transport_name);
Patrik Höglunde2d6a062017-10-05 12:53:33215 }
216
217 // The URL of the ICE server which this candidate is gathered from.
218 const std::string& url() const { return url_; }
Niels Möllerd4aa3a32021-09-29 11:23:01219 void set_url(absl::string_view url) { Assign(url_, url); }
Patrik Höglunde2d6a062017-10-05 12:53:33220
221 // Determines whether this candidate is equivalent to the given one.
Steve Anton36b28db2017-10-26 18:27:17222 bool IsEquivalent(const Candidate& c) const;
Patrik Höglunde2d6a062017-10-05 12:53:33223
224 // Determines whether this candidate can be considered equivalent to the
225 // given one when looking for a matching candidate to remove.
Steve Anton36b28db2017-10-26 18:27:17226 bool MatchesForRemoval(const Candidate& c) const;
Patrik Höglunde2d6a062017-10-05 12:53:33227
Yves Gerey665174f2018-06-19 13:03:05228 std::string ToString() const { return ToStringInternal(false); }
Patrik Höglunde2d6a062017-10-05 12:53:33229
Yves Gerey665174f2018-06-19 13:03:05230 std::string ToSensitiveString() const { return ToStringInternal(true); }
Patrik Höglunde2d6a062017-10-05 12:53:33231
232 uint32_t GetPriority(uint32_t type_preference,
233 int network_adapter_preference,
Philipp Hancke17ec0562023-06-16 11:58:45234 int relay_preference,
235 bool adjust_local_preference) const;
Patrik Höglunde2d6a062017-10-05 12:53:33236
Steve Anton36b28db2017-10-26 18:27:17237 bool operator==(const Candidate& o) const;
238 bool operator!=(const Candidate& o) const;
Patrik Höglunde2d6a062017-10-05 12:53:33239
Qingsi Wang1dac6d82018-12-12 23:28:47240 // Returns a sanitized copy configured by the given booleans. If
Artem Titov0e61fdd2021-07-25 19:50:14241 // `use_host_address` is true, the returned copy has its IP removed from
242 // `address()`, which leads `address()` to be a hostname address. If
243 // `filter_related_address`, the returned copy has its related address reset
Qingsi Wang1dac6d82018-12-12 23:28:47244 // to the wildcard address (i.e. 0.0.0.0 for IPv4 and :: for IPv6). Note that
245 // setting both booleans to false returns an identical copy to the original
246 // candidate.
247 Candidate ToSanitizedCopy(bool use_hostname_address,
248 bool filter_related_address) const;
249
Tommif2431a92024-02-20 14:27:44250 // Computes and populates the `foundation()` field.
251 // Foundation: An arbitrary string that is the same for two candidates
252 // that have the same type, base IP address, protocol (UDP, TCP,
253 // etc.), and STUN or TURN server. If any of these are different,
254 // then the foundation will be different. Two candidate pairs with
255 // the same foundation pairs are likely to have similar network
256 // characteristics. Foundations are used in the frozen algorithm.
Christoffer Dewerin7098d112024-02-26 14:38:44257 // A session wide (peerconnection) tie-breaker is applied to the foundation,
Tommif2431a92024-02-20 14:27:44258 // adds additional randomness and must be the same for all candidates.
Christoffer Dewerin7098d112024-02-26 14:38:44259 void ComputeFoundation(const rtc::SocketAddress& base_address,
260 uint64_t tie_breaker);
Tommif2431a92024-02-20 14:27:44261
262 // https://www.rfc-editor.org/rfc/rfc5245#section-7.2.1.3
263 // Call to populate the foundation field for a new peer reflexive remote
264 // candidate. The type of the candidate must be "prflx".
265 // The foundation of the candidate is set to an arbitrary value, different
266 // from the foundation for all other remote candidates.
267 void ComputePrflxFoundation();
268
Patrik Höglunde2d6a062017-10-05 12:53:33269 private:
Niels Möllerd4aa3a32021-09-29 11:23:01270 // TODO(bugs.webrtc.org/13220): With C++17, we get a std::string assignment
271 // operator accepting any object implicitly convertible to std::string_view,
272 // and then we don't need this workaround.
273 static void Assign(std::string& s, absl::string_view view);
Steve Anton36b28db2017-10-26 18:27:17274 std::string ToStringInternal(bool sensitive) const;
Patrik Höglunde2d6a062017-10-05 12:53:33275
276 std::string id_;
277 int component_;
278 std::string protocol_;
279 std::string relay_protocol_;
280 rtc::SocketAddress address_;
281 uint32_t priority_;
282 std::string username_;
283 std::string password_;
Tommic7a4b2a2024-02-25 22:34:39284 webrtc::IceCandidateType type_ = webrtc::IceCandidateType::kHost;
Patrik Höglunde2d6a062017-10-05 12:53:33285 std::string network_name_;
286 rtc::AdapterType network_type_;
Jonas Oreland0d13bbd2022-03-02 10:17:36287 rtc::AdapterType underlying_type_for_vpn_;
Patrik Höglunde2d6a062017-10-05 12:53:33288 uint32_t generation_;
289 std::string foundation_;
290 rtc::SocketAddress related_address_;
291 std::string tcptype_;
292 std::string transport_name_;
293 uint16_t network_id_;
294 uint16_t network_cost_;
295 std::string url_;
296};
297
298} // namespace cricket
299
300#endif // API_CANDIDATE_H_