blob: 4ec7a891df41fcfc7a4582f6b495ba5fcb5417d0 [file] [log] [blame]
deadbeef1dcb1642017-03-29 21:08:16 -07001/*
2 * Copyright 2012 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 <string>
12#include <vector>
13
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020014#include "pc/iceserverparsing.h"
15#include "rtc_base/gunit.h"
deadbeef1dcb1642017-03-29 21:08:16 -070016
17namespace webrtc {
18
19class IceServerParsingTest : public testing::Test {
20 public:
21 // Convenience functions for parsing a single URL. Result is stored in
22 // |stun_servers_| and |turn_servers_|.
23 bool ParseUrl(const std::string& url) {
24 return ParseUrl(url, std::string(), std::string());
25 }
26
27 bool ParseTurnUrl(const std::string& url) {
28 return ParseUrl(url, "username", "password");
29 }
30
31 bool ParseUrl(const std::string& url,
32 const std::string& username,
33 const std::string& password) {
34 return ParseUrl(
35 url, username, password,
36 PeerConnectionInterface::TlsCertPolicy::kTlsCertPolicySecure);
37 }
38
39 bool ParseUrl(const std::string& url,
40 const std::string& username,
41 const std::string& password,
42 PeerConnectionInterface::TlsCertPolicy tls_certificate_policy) {
Emad Omaradab1d2d2017-06-16 15:43:11 -070043 return ParseUrl(url, username, password, tls_certificate_policy, "");
44 }
45
46 bool ParseUrl(const std::string& url,
47 const std::string& username,
48 const std::string& password,
49 PeerConnectionInterface::TlsCertPolicy tls_certificate_policy,
50 const std::string& hostname) {
deadbeef1dcb1642017-03-29 21:08:16 -070051 stun_servers_.clear();
52 turn_servers_.clear();
53 PeerConnectionInterface::IceServers servers;
54 PeerConnectionInterface::IceServer server;
55 server.urls.push_back(url);
56 server.username = username;
57 server.password = password;
58 server.tls_cert_policy = tls_certificate_policy;
Emad Omaradab1d2d2017-06-16 15:43:11 -070059 server.hostname = hostname;
deadbeef1dcb1642017-03-29 21:08:16 -070060 servers.push_back(server);
61 return webrtc::ParseIceServers(servers, &stun_servers_, &turn_servers_) ==
62 webrtc::RTCErrorType::NONE;
63 }
64
65 protected:
66 cricket::ServerAddresses stun_servers_;
67 std::vector<cricket::RelayServerConfig> turn_servers_;
68};
69
70// Make sure all STUN/TURN prefixes are parsed correctly.
71TEST_F(IceServerParsingTest, ParseStunPrefixes) {
72 EXPECT_TRUE(ParseUrl("stun:hostname"));
73 EXPECT_EQ(1U, stun_servers_.size());
74 EXPECT_EQ(0U, turn_servers_.size());
75
76 EXPECT_TRUE(ParseUrl("stuns:hostname"));
77 EXPECT_EQ(1U, stun_servers_.size());
78 EXPECT_EQ(0U, turn_servers_.size());
79
80 EXPECT_TRUE(ParseTurnUrl("turn:hostname"));
81 EXPECT_EQ(0U, stun_servers_.size());
82 EXPECT_EQ(1U, turn_servers_.size());
83 EXPECT_EQ(cricket::PROTO_UDP, turn_servers_[0].ports[0].proto);
84
85 EXPECT_TRUE(ParseTurnUrl("turns:hostname"));
86 EXPECT_EQ(0U, stun_servers_.size());
87 EXPECT_EQ(1U, turn_servers_.size());
88 EXPECT_EQ(cricket::PROTO_TLS, turn_servers_[0].ports[0].proto);
89 EXPECT_TRUE(turn_servers_[0].tls_cert_policy ==
90 cricket::TlsCertPolicy::TLS_CERT_POLICY_SECURE);
91
92 EXPECT_TRUE(ParseUrl(
93 "turns:hostname", "username", "password",
94 PeerConnectionInterface::TlsCertPolicy::kTlsCertPolicyInsecureNoCheck));
95 EXPECT_EQ(0U, stun_servers_.size());
96 EXPECT_EQ(1U, turn_servers_.size());
97 EXPECT_TRUE(turn_servers_[0].tls_cert_policy ==
98 cricket::TlsCertPolicy::TLS_CERT_POLICY_INSECURE_NO_CHECK);
99 EXPECT_EQ(cricket::PROTO_TLS, turn_servers_[0].ports[0].proto);
100
101 // invalid prefixes
102 EXPECT_FALSE(ParseUrl("stunn:hostname"));
103 EXPECT_FALSE(ParseUrl(":hostname"));
104 EXPECT_FALSE(ParseUrl(":"));
105 EXPECT_FALSE(ParseUrl(""));
106}
107
108TEST_F(IceServerParsingTest, VerifyDefaults) {
109 // TURNS defaults
110 EXPECT_TRUE(ParseTurnUrl("turns:hostname"));
111 EXPECT_EQ(1U, turn_servers_.size());
112 EXPECT_EQ(5349, turn_servers_[0].ports[0].address.port());
113 EXPECT_EQ(cricket::PROTO_TLS, turn_servers_[0].ports[0].proto);
114
115 // TURN defaults
116 EXPECT_TRUE(ParseTurnUrl("turn:hostname"));
117 EXPECT_EQ(1U, turn_servers_.size());
118 EXPECT_EQ(3478, turn_servers_[0].ports[0].address.port());
119 EXPECT_EQ(cricket::PROTO_UDP, turn_servers_[0].ports[0].proto);
120
121 // STUN defaults
122 EXPECT_TRUE(ParseUrl("stun:hostname"));
123 EXPECT_EQ(1U, stun_servers_.size());
124 EXPECT_EQ(3478, stun_servers_.begin()->port());
125}
126
127// Check that the 6 combinations of IPv4/IPv6/hostname and with/without port
128// can be parsed correctly.
129TEST_F(IceServerParsingTest, ParseHostnameAndPort) {
130 EXPECT_TRUE(ParseUrl("stun:1.2.3.4:1234"));
131 EXPECT_EQ(1U, stun_servers_.size());
132 EXPECT_EQ("1.2.3.4", stun_servers_.begin()->hostname());
133 EXPECT_EQ(1234, stun_servers_.begin()->port());
134
135 EXPECT_TRUE(ParseUrl("stun:[1:2:3:4:5:6:7:8]:4321"));
136 EXPECT_EQ(1U, stun_servers_.size());
137 EXPECT_EQ("1:2:3:4:5:6:7:8", stun_servers_.begin()->hostname());
138 EXPECT_EQ(4321, stun_servers_.begin()->port());
139
140 EXPECT_TRUE(ParseUrl("stun:hostname:9999"));
141 EXPECT_EQ(1U, stun_servers_.size());
142 EXPECT_EQ("hostname", stun_servers_.begin()->hostname());
143 EXPECT_EQ(9999, stun_servers_.begin()->port());
144
145 EXPECT_TRUE(ParseUrl("stun:1.2.3.4"));
146 EXPECT_EQ(1U, stun_servers_.size());
147 EXPECT_EQ("1.2.3.4", stun_servers_.begin()->hostname());
148 EXPECT_EQ(3478, stun_servers_.begin()->port());
149
150 EXPECT_TRUE(ParseUrl("stun:[1:2:3:4:5:6:7:8]"));
151 EXPECT_EQ(1U, stun_servers_.size());
152 EXPECT_EQ("1:2:3:4:5:6:7:8", stun_servers_.begin()->hostname());
153 EXPECT_EQ(3478, stun_servers_.begin()->port());
154
155 EXPECT_TRUE(ParseUrl("stun:hostname"));
156 EXPECT_EQ(1U, stun_servers_.size());
157 EXPECT_EQ("hostname", stun_servers_.begin()->hostname());
158 EXPECT_EQ(3478, stun_servers_.begin()->port());
159
Emad Omaradab1d2d2017-06-16 15:43:11 -0700160 // Both TURN IP and host exist
161 EXPECT_TRUE(
162 ParseUrl("turn:1.2.3.4:1234", "username", "password",
163 PeerConnectionInterface::TlsCertPolicy::kTlsCertPolicySecure,
164 "hostname"));
165 EXPECT_EQ(1U, turn_servers_.size());
166 rtc::SocketAddress address = turn_servers_[0].ports[0].address;
167 EXPECT_EQ("hostname", address.hostname());
168 EXPECT_EQ(1234, address.port());
169 EXPECT_FALSE(address.IsUnresolvedIP());
170 EXPECT_EQ("1.2.3.4", address.ipaddr().ToString());
171
deadbeef1dcb1642017-03-29 21:08:16 -0700172 // Try some invalid hostname:port strings.
173 EXPECT_FALSE(ParseUrl("stun:hostname:99a99"));
174 EXPECT_FALSE(ParseUrl("stun:hostname:-1"));
175 EXPECT_FALSE(ParseUrl("stun:hostname:port:more"));
176 EXPECT_FALSE(ParseUrl("stun:hostname:port more"));
177 EXPECT_FALSE(ParseUrl("stun:hostname:"));
178 EXPECT_FALSE(ParseUrl("stun:[1:2:3:4:5:6:7:8]junk:1000"));
179 EXPECT_FALSE(ParseUrl("stun::5555"));
180 EXPECT_FALSE(ParseUrl("stun:"));
181}
182
183// Test parsing the "?transport=xxx" part of the URL.
184TEST_F(IceServerParsingTest, ParseTransport) {
185 EXPECT_TRUE(ParseTurnUrl("turn:hostname:1234?transport=tcp"));
186 EXPECT_EQ(1U, turn_servers_.size());
187 EXPECT_EQ(cricket::PROTO_TCP, turn_servers_[0].ports[0].proto);
188
189 EXPECT_TRUE(ParseTurnUrl("turn:hostname?transport=udp"));
190 EXPECT_EQ(1U, turn_servers_.size());
191 EXPECT_EQ(cricket::PROTO_UDP, turn_servers_[0].ports[0].proto);
192
193 EXPECT_FALSE(ParseTurnUrl("turn:hostname?transport=invalid"));
194 EXPECT_FALSE(ParseTurnUrl("turn:hostname?transport="));
195 EXPECT_FALSE(ParseTurnUrl("turn:hostname?="));
196 EXPECT_FALSE(ParseTurnUrl("turn:hostname?"));
197 EXPECT_FALSE(ParseTurnUrl("?"));
198}
199
200// Test parsing ICE username contained in URL.
201TEST_F(IceServerParsingTest, ParseUsername) {
202 EXPECT_TRUE(ParseTurnUrl("turn:user@hostname"));
203 EXPECT_EQ(1U, turn_servers_.size());
204 EXPECT_EQ("user", turn_servers_[0].credentials.username);
205
206 EXPECT_FALSE(ParseTurnUrl("turn:@hostname"));
207 EXPECT_FALSE(ParseTurnUrl("turn:username@"));
208 EXPECT_FALSE(ParseTurnUrl("turn:@"));
209 EXPECT_FALSE(ParseTurnUrl("turn:user@name@hostname"));
210}
211
212// Test that username and password from IceServer is copied into the resulting
213// RelayServerConfig.
214TEST_F(IceServerParsingTest, CopyUsernameAndPasswordFromIceServer) {
215 EXPECT_TRUE(ParseUrl("turn:hostname", "username", "password"));
216 EXPECT_EQ(1U, turn_servers_.size());
217 EXPECT_EQ("username", turn_servers_[0].credentials.username);
218 EXPECT_EQ("password", turn_servers_[0].credentials.password);
219}
220
221// Ensure that if a server has multiple URLs, each one is parsed.
222TEST_F(IceServerParsingTest, ParseMultipleUrls) {
223 PeerConnectionInterface::IceServers servers;
224 PeerConnectionInterface::IceServer server;
225 server.urls.push_back("stun:hostname");
226 server.urls.push_back("turn:hostname");
227 server.username = "foo";
228 server.password = "bar";
229 servers.push_back(server);
230 EXPECT_EQ(webrtc::RTCErrorType::NONE,
231 webrtc::ParseIceServers(servers, &stun_servers_, &turn_servers_));
232 EXPECT_EQ(1U, stun_servers_.size());
233 EXPECT_EQ(1U, turn_servers_.size());
234}
235
236// Ensure that TURN servers are given unique priorities,
237// so that their resulting candidates have unique priorities.
238TEST_F(IceServerParsingTest, TurnServerPrioritiesUnique) {
239 PeerConnectionInterface::IceServers servers;
240 PeerConnectionInterface::IceServer server;
241 server.urls.push_back("turn:hostname");
242 server.urls.push_back("turn:hostname2");
243 server.username = "foo";
244 server.password = "bar";
245 servers.push_back(server);
246 EXPECT_EQ(webrtc::RTCErrorType::NONE,
247 webrtc::ParseIceServers(servers, &stun_servers_, &turn_servers_));
248 EXPECT_EQ(2U, turn_servers_.size());
249 EXPECT_NE(turn_servers_[0].priority, turn_servers_[1].priority);
250}
251
252} // namespace webrtc