1 /*
2  *  Copyright 2017 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 #include "api/candidate.h"
12 
13 #include "rtc_base/helpers.h"
14 #include "rtc_base/ip_address.h"
15 #include "rtc_base/strings/string_builder.h"
16 
17 namespace cricket {
18 
Candidate()19 Candidate::Candidate()
20     : id_(rtc::CreateRandomString(8)),
21       component_(0),
22       priority_(0),
23       network_type_(rtc::ADAPTER_TYPE_UNKNOWN),
24       generation_(0),
25       network_id_(0),
26       network_cost_(0) {}
27 
Candidate(int component,const std::string & protocol,const rtc::SocketAddress & address,uint32_t priority,const std::string & username,const std::string & password,const std::string & type,uint32_t generation,const std::string & foundation,uint16_t network_id,uint16_t network_cost)28 Candidate::Candidate(int component,
29                      const std::string& protocol,
30                      const rtc::SocketAddress& address,
31                      uint32_t priority,
32                      const std::string& username,
33                      const std::string& password,
34                      const std::string& type,
35                      uint32_t generation,
36                      const std::string& foundation,
37                      uint16_t network_id,
38                      uint16_t network_cost)
39     : id_(rtc::CreateRandomString(8)),
40       component_(component),
41       protocol_(protocol),
42       address_(address),
43       priority_(priority),
44       username_(username),
45       password_(password),
46       type_(type),
47       network_type_(rtc::ADAPTER_TYPE_UNKNOWN),
48       generation_(generation),
49       foundation_(foundation),
50       network_id_(network_id),
51       network_cost_(network_cost) {}
52 
53 Candidate::Candidate(const Candidate&) = default;
54 
55 Candidate::~Candidate() = default;
56 
IsEquivalent(const Candidate & c) const57 bool Candidate::IsEquivalent(const Candidate& c) const {
58   // We ignore the network name, since that is just debug information, and
59   // the priority and the network cost, since they should be the same if the
60   // rest are.
61   return (component_ == c.component_) && (protocol_ == c.protocol_) &&
62          (address_ == c.address_) && (username_ == c.username_) &&
63          (password_ == c.password_) && (type_ == c.type_) &&
64          (generation_ == c.generation_) && (foundation_ == c.foundation_) &&
65          (related_address_ == c.related_address_) &&
66          (network_id_ == c.network_id_);
67 }
68 
MatchesForRemoval(const Candidate & c) const69 bool Candidate::MatchesForRemoval(const Candidate& c) const {
70   return component_ == c.component_ && protocol_ == c.protocol_ &&
71          address_ == c.address_;
72 }
73 
ToStringInternal(bool sensitive) const74 std::string Candidate::ToStringInternal(bool sensitive) const {
75   rtc::StringBuilder ost;
76   std::string address =
77       sensitive ? address_.ToSensitiveString() : address_.ToString();
78   ost << "Cand[" << transport_name_ << ":" << foundation_ << ":" << component_
79       << ":" << protocol_ << ":" << priority_ << ":" << address << ":" << type_
80       << ":" << related_address_.ToString() << ":" << username_ << ":"
81       << password_ << ":" << network_id_ << ":" << network_cost_ << ":"
82       << generation_ << "]";
83   return ost.Release();
84 }
85 
GetPriority(uint32_t type_preference,int network_adapter_preference,int relay_preference) const86 uint32_t Candidate::GetPriority(uint32_t type_preference,
87                                 int network_adapter_preference,
88                                 int relay_preference) const {
89   // RFC 5245 - 4.1.2.1.
90   // priority = (2^24)*(type preference) +
91   //            (2^8)*(local preference) +
92   //            (2^0)*(256 - component ID)
93 
94   // |local_preference| length is 2 bytes, 0-65535 inclusive.
95   // In our implemenation we will partion local_preference into
96   //              0                 1
97   //       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
98   //      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
99   //      |  NIC Pref     |    Addr Pref  |
100   //      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
101   // NIC Type - Type of the network adapter e.g. 3G/Wifi/Wired.
102   // Addr Pref - Address preference value as per RFC 3484.
103   // local preference =  (NIC Type << 8 | Addr_Pref) - relay preference.
104 
105   int addr_pref = IPAddressPrecedence(address_.ipaddr());
106   int local_preference =
107       ((network_adapter_preference << 8) | addr_pref) + relay_preference;
108 
109   return (type_preference << 24) | (local_preference << 8) | (256 - component_);
110 }
111 
operator ==(const Candidate & o) const112 bool Candidate::operator==(const Candidate& o) const {
113   return id_ == o.id_ && component_ == o.component_ &&
114          protocol_ == o.protocol_ && relay_protocol_ == o.relay_protocol_ &&
115          address_ == o.address_ && priority_ == o.priority_ &&
116          username_ == o.username_ && password_ == o.password_ &&
117          type_ == o.type_ && network_name_ == o.network_name_ &&
118          network_type_ == o.network_type_ && generation_ == o.generation_ &&
119          foundation_ == o.foundation_ &&
120          related_address_ == o.related_address_ && tcptype_ == o.tcptype_ &&
121          transport_name_ == o.transport_name_ && network_id_ == o.network_id_;
122 }
123 
operator !=(const Candidate & o) const124 bool Candidate::operator!=(const Candidate& o) const {
125   return !(*this == o);
126 }
127 
ToSanitizedCopy(bool use_hostname_address,bool filter_related_address) const128 Candidate Candidate::ToSanitizedCopy(bool use_hostname_address,
129                                      bool filter_related_address) const {
130   Candidate copy(*this);
131   if (use_hostname_address) {
132     rtc::SocketAddress hostname_only_addr(address().hostname(),
133                                           address().port());
134     copy.set_address(hostname_only_addr);
135   }
136   if (filter_related_address) {
137     copy.set_related_address(
138         rtc::EmptySocketAddressWithFamily(copy.address().family()));
139   }
140   return copy;
141 }
142 
143 }  // namespace cricket
144