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