blob: 19eed8cc32085718aeeb97071bef082f94076f1e [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
2 * libjingle
3 * Copyright 2004--2005, Google Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#ifndef TALK_P2P_BASE_CANDIDATE_H_
29#define TALK_P2P_BASE_CANDIDATE_H_
30
31#include <climits>
32#include <cmath>
33#include <string>
34#include <sstream>
35#include <iomanip>
36#include "talk/base/basictypes.h"
37#include "talk/base/socketaddress.h"
38#include "talk/p2p/base/constants.h"
39
40namespace cricket {
41
42// Candidate for ICE based connection discovery.
43
44class Candidate {
45 public:
46 // TODO: Match the ordering and param list as per RFC 5245
47 // candidate-attribute syntax. http://tools.ietf.org/html/rfc5245#section-15.1
48 Candidate() : component_(0), priority_(0), generation_(0) {}
49 Candidate(const std::string& id, int component, const std::string& protocol,
50 const talk_base::SocketAddress& address, uint32 priority,
51 const std::string& username, const std::string& password,
52 const std::string& type, const std::string& network_name,
53 uint32 generation, const std::string& foundation)
54 : id_(id), component_(component), protocol_(protocol), address_(address),
55 priority_(priority), username_(username), password_(password),
56 type_(type), network_name_(network_name), generation_(generation),
57 foundation_(foundation) {
58 }
59
60 const std::string & id() const { return id_; }
61 void set_id(const std::string & id) { id_ = id; }
62
63 int component() const { return component_; }
64 void set_component(int component) { component_ = component; }
65
66 const std::string & protocol() const { return protocol_; }
67 void set_protocol(const std::string & protocol) { protocol_ = protocol; }
68
69 const talk_base::SocketAddress & address() const { return address_; }
70 void set_address(const talk_base::SocketAddress & address) {
71 address_ = address;
72 }
73
74 uint32 priority() const { return priority_; }
75 void set_priority(const uint32 priority) { priority_ = priority; }
76
77// void set_type_preference(uint32 type_preference) {
78// priority_ = GetPriority(type_preference);
79// }
80
81 // Maps old preference (which was 0.0-1.0) to match priority (which
82 // is 0-2^32-1) to to match RFC 5245, section 4.1.2.1. Also see
83 // https://docs.google.com/a/google.com/document/d/
84 // 1iNQDiwDKMh0NQOrCqbj3DKKRT0Dn5_5UJYhmZO-t7Uc/edit
85 float preference() const {
86 // The preference value is clamped to two decimal precision.
87 return static_cast<float>(((priority_ >> 24) * 100 / 127) / 100.0);
88 }
89
90 void set_preference(float preference) {
91 // Limiting priority to UINT_MAX when value exceeds uint32 max.
92 // This can happen for e.g. when preference = 3.
93 uint64 prio_val = static_cast<uint64>(preference * 127) << 24;
94 priority_ = static_cast<uint32>(
95 talk_base::_min(prio_val, static_cast<uint64>(UINT_MAX)));
96 }
97
98 const std::string & username() const { return username_; }
99 void set_username(const std::string & username) { username_ = username; }
100
101 const std::string & password() const { return password_; }
102 void set_password(const std::string & password) { password_ = password; }
103
104 const std::string & type() const { return type_; }
105 void set_type(const std::string & type) { type_ = type; }
106
107 const std::string & network_name() const { return network_name_; }
108 void set_network_name(const std::string & network_name) {
109 network_name_ = network_name;
110 }
111
112 // Candidates in a new generation replace those in the old generation.
113 uint32 generation() const { return generation_; }
114 void set_generation(uint32 generation) { generation_ = generation; }
115 const std::string generation_str() const {
116 std::ostringstream ost;
117 ost << generation_;
118 return ost.str();
119 }
120 void set_generation_str(const std::string& str) {
121 std::istringstream ist(str);
122 ist >> generation_;
123 }
124
125 const std::string& foundation() const {
126 return foundation_;
127 }
128
129 void set_foundation(const std::string& foundation) {
130 foundation_ = foundation;
131 }
132
133 const talk_base::SocketAddress & related_address() const {
134 return related_address_;
135 }
136 void set_related_address(
137 const talk_base::SocketAddress & related_address) {
138 related_address_ = related_address;
139 }
140
141 // Determines whether this candidate is equivalent to the given one.
142 bool IsEquivalent(const Candidate& c) const {
143 // We ignore the network name, since that is just debug information, and
144 // the priority, since that should be the same if the rest is (and it's
145 // a float so equality checking is always worrisome).
146 return (id_ == c.id_) &&
147 (component_ == c.component_) &&
148 (protocol_ == c.protocol_) &&
149 (address_ == c.address_) &&
150 (username_ == c.username_) &&
151 (password_ == c.password_) &&
152 (type_ == c.type_) &&
153 (generation_ == c.generation_) &&
154 (foundation_ == c.foundation_) &&
155 (related_address_ == c.related_address_);
156 }
157
158 std::string ToString() const {
159 return ToStringInternal(false);
160 }
161
162 std::string ToSensitiveString() const {
163 return ToStringInternal(true);
164 }
165
wu@webrtc.org0de29502014-02-13 19:54:28 +0000166 uint32 GetPriority(uint32 type_preference) const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000167 // RFC 5245 - 4.1.2.1.
168 // priority = (2^24)*(type preference) +
169 // (2^8)*(local preference) +
170 // (2^0)*(256 - component ID)
171 int addr_pref = IPAddressPrecedence(address_.ipaddr());
wu@webrtc.org0de29502014-02-13 19:54:28 +0000172 return (type_preference << 24) | (addr_pref << 8) | (256 - component_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000173 }
174
175 private:
176 std::string ToStringInternal(bool sensitive) const {
177 std::ostringstream ost;
178 std::string address = sensitive ? address_.ToSensitiveString() :
179 address_.ToString();
wu@webrtc.org0de29502014-02-13 19:54:28 +0000180 ost << "Cand[" << id_ << ":" << component_ << ":"
181 << type_ << ":" << protocol_ << ":"
182 << network_name_ << ":" << address << ":"
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000183 << username_ << ":" << password_ << "]";
184 return ost.str();
185 }
186
187 std::string id_;
188 int component_;
189 std::string protocol_;
190 talk_base::SocketAddress address_;
191 uint32 priority_;
192 std::string username_;
193 std::string password_;
194 std::string type_;
195 std::string network_name_;
196 uint32 generation_;
197 std::string foundation_;
198 talk_base::SocketAddress related_address_;
199};
200
201} // namespace cricket
202
203#endif // TALK_P2P_BASE_CANDIDATE_H_