xref: /aosp_15_r20/external/webrtc/pc/ice_server_parsing_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
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 "pc/ice_server_parsing.h"
12 
13 #include <string>
14 #include <vector>
15 
16 #include "p2p/base/port_interface.h"
17 #include "rtc_base/ip_address.h"
18 #include "rtc_base/socket_address.h"
19 #include "test/gtest.h"
20 
21 namespace webrtc {
22 
23 class IceServerParsingTest : public ::testing::Test {
24  public:
25   // Convenience functions for parsing a single URL. Result is stored in
26   // `stun_servers_` and `turn_servers_`.
ParseUrl(const std::string & url)27   bool ParseUrl(const std::string& url) {
28     return ParseUrl(url, std::string(), std::string());
29   }
30 
ParseTurnUrl(const std::string & url)31   bool ParseTurnUrl(const std::string& url) {
32     return ParseUrl(url, "username", "password");
33   }
34 
ParseUrl(const std::string & url,const std::string & username,const std::string & password)35   bool ParseUrl(const std::string& url,
36                 const std::string& username,
37                 const std::string& password) {
38     return ParseUrl(
39         url, username, password,
40         PeerConnectionInterface::TlsCertPolicy::kTlsCertPolicySecure);
41   }
42 
ParseUrl(const std::string & url,const std::string & username,const std::string & password,PeerConnectionInterface::TlsCertPolicy tls_certificate_policy)43   bool ParseUrl(const std::string& url,
44                 const std::string& username,
45                 const std::string& password,
46                 PeerConnectionInterface::TlsCertPolicy tls_certificate_policy) {
47     return ParseUrl(url, username, password, tls_certificate_policy, "");
48   }
49 
ParseUrl(const std::string & url,const std::string & username,const std::string & password,PeerConnectionInterface::TlsCertPolicy tls_certificate_policy,const std::string & hostname)50   bool ParseUrl(const std::string& url,
51                 const std::string& username,
52                 const std::string& password,
53                 PeerConnectionInterface::TlsCertPolicy tls_certificate_policy,
54                 const std::string& hostname) {
55     stun_servers_.clear();
56     turn_servers_.clear();
57     PeerConnectionInterface::IceServers servers;
58     PeerConnectionInterface::IceServer server;
59     server.urls.push_back(url);
60     server.username = username;
61     server.password = password;
62     server.tls_cert_policy = tls_certificate_policy;
63     server.hostname = hostname;
64     servers.push_back(server);
65     return webrtc::ParseIceServersOrError(servers, &stun_servers_,
66                                           &turn_servers_)
67         .ok();
68   }
69 
70  protected:
71   cricket::ServerAddresses stun_servers_;
72   std::vector<cricket::RelayServerConfig> turn_servers_;
73 };
74 
75 // Make sure all STUN/TURN prefixes are parsed correctly.
TEST_F(IceServerParsingTest,ParseStunPrefixes)76 TEST_F(IceServerParsingTest, ParseStunPrefixes) {
77   EXPECT_TRUE(ParseUrl("stun:hostname"));
78   EXPECT_EQ(1U, stun_servers_.size());
79   EXPECT_EQ(0U, turn_servers_.size());
80 
81   EXPECT_TRUE(ParseUrl("stuns:hostname"));
82   EXPECT_EQ(1U, stun_servers_.size());
83   EXPECT_EQ(0U, turn_servers_.size());
84 
85   EXPECT_TRUE(ParseTurnUrl("turn:hostname"));
86   EXPECT_EQ(0U, stun_servers_.size());
87   EXPECT_EQ(1U, turn_servers_.size());
88   EXPECT_EQ(cricket::PROTO_UDP, turn_servers_[0].ports[0].proto);
89 
90   EXPECT_TRUE(ParseTurnUrl("turns:hostname"));
91   EXPECT_EQ(0U, stun_servers_.size());
92   EXPECT_EQ(1U, turn_servers_.size());
93   EXPECT_EQ(cricket::PROTO_TLS, turn_servers_[0].ports[0].proto);
94   EXPECT_TRUE(turn_servers_[0].tls_cert_policy ==
95               cricket::TlsCertPolicy::TLS_CERT_POLICY_SECURE);
96 
97   EXPECT_TRUE(ParseUrl(
98       "turns:hostname", "username", "password",
99       PeerConnectionInterface::TlsCertPolicy::kTlsCertPolicyInsecureNoCheck));
100   EXPECT_EQ(0U, stun_servers_.size());
101   EXPECT_EQ(1U, turn_servers_.size());
102   EXPECT_TRUE(turn_servers_[0].tls_cert_policy ==
103               cricket::TlsCertPolicy::TLS_CERT_POLICY_INSECURE_NO_CHECK);
104   EXPECT_EQ(cricket::PROTO_TLS, turn_servers_[0].ports[0].proto);
105 
106   // invalid prefixes
107   EXPECT_FALSE(ParseUrl("stunn:hostname"));
108   EXPECT_FALSE(ParseUrl(":hostname"));
109   EXPECT_FALSE(ParseUrl(":"));
110   EXPECT_FALSE(ParseUrl(""));
111 }
112 
TEST_F(IceServerParsingTest,VerifyDefaults)113 TEST_F(IceServerParsingTest, VerifyDefaults) {
114   // TURNS defaults
115   EXPECT_TRUE(ParseTurnUrl("turns:hostname"));
116   EXPECT_EQ(1U, turn_servers_.size());
117   EXPECT_EQ(5349, turn_servers_[0].ports[0].address.port());
118   EXPECT_EQ(cricket::PROTO_TLS, turn_servers_[0].ports[0].proto);
119 
120   // TURN defaults
121   EXPECT_TRUE(ParseTurnUrl("turn:hostname"));
122   EXPECT_EQ(1U, turn_servers_.size());
123   EXPECT_EQ(3478, turn_servers_[0].ports[0].address.port());
124   EXPECT_EQ(cricket::PROTO_UDP, turn_servers_[0].ports[0].proto);
125 
126   // STUN defaults
127   EXPECT_TRUE(ParseUrl("stun:hostname"));
128   EXPECT_EQ(1U, stun_servers_.size());
129   EXPECT_EQ(3478, stun_servers_.begin()->port());
130 }
131 
132 // Check that the 6 combinations of IPv4/IPv6/hostname and with/without port
133 // can be parsed correctly.
TEST_F(IceServerParsingTest,ParseHostnameAndPort)134 TEST_F(IceServerParsingTest, ParseHostnameAndPort) {
135   EXPECT_TRUE(ParseUrl("stun:1.2.3.4:1234"));
136   EXPECT_EQ(1U, stun_servers_.size());
137   EXPECT_EQ("1.2.3.4", stun_servers_.begin()->hostname());
138   EXPECT_EQ(1234, stun_servers_.begin()->port());
139 
140   EXPECT_TRUE(ParseUrl("stun:[1:2:3:4:5:6:7:8]:4321"));
141   EXPECT_EQ(1U, stun_servers_.size());
142   EXPECT_EQ("1:2:3:4:5:6:7:8", stun_servers_.begin()->hostname());
143   EXPECT_EQ(4321, stun_servers_.begin()->port());
144 
145   EXPECT_TRUE(ParseUrl("stun:hostname:9999"));
146   EXPECT_EQ(1U, stun_servers_.size());
147   EXPECT_EQ("hostname", stun_servers_.begin()->hostname());
148   EXPECT_EQ(9999, stun_servers_.begin()->port());
149 
150   EXPECT_TRUE(ParseUrl("stun:1.2.3.4"));
151   EXPECT_EQ(1U, stun_servers_.size());
152   EXPECT_EQ("1.2.3.4", stun_servers_.begin()->hostname());
153   EXPECT_EQ(3478, stun_servers_.begin()->port());
154 
155   EXPECT_TRUE(ParseUrl("stun:[1:2:3:4:5:6:7:8]"));
156   EXPECT_EQ(1U, stun_servers_.size());
157   EXPECT_EQ("1:2:3:4:5:6:7:8", stun_servers_.begin()->hostname());
158   EXPECT_EQ(3478, stun_servers_.begin()->port());
159 
160   EXPECT_TRUE(ParseUrl("stun:hostname"));
161   EXPECT_EQ(1U, stun_servers_.size());
162   EXPECT_EQ("hostname", stun_servers_.begin()->hostname());
163   EXPECT_EQ(3478, stun_servers_.begin()->port());
164 
165   // Both TURN IP and host exist
166   EXPECT_TRUE(
167       ParseUrl("turn:1.2.3.4:1234", "username", "password",
168                PeerConnectionInterface::TlsCertPolicy::kTlsCertPolicySecure,
169                "hostname"));
170   EXPECT_EQ(1U, turn_servers_.size());
171   rtc::SocketAddress address = turn_servers_[0].ports[0].address;
172   EXPECT_EQ("hostname", address.hostname());
173   EXPECT_EQ(1234, address.port());
174   EXPECT_FALSE(address.IsUnresolvedIP());
175   EXPECT_EQ("1.2.3.4", address.ipaddr().ToString());
176 
177   // Try some invalid hostname:port strings.
178   EXPECT_FALSE(ParseUrl("stun:hostname:99a99"));
179   EXPECT_FALSE(ParseUrl("stun:hostname:-1"));
180   EXPECT_FALSE(ParseUrl("stun:hostname:port:more"));
181   EXPECT_FALSE(ParseUrl("stun:hostname:port more"));
182   EXPECT_FALSE(ParseUrl("stun:hostname:"));
183   EXPECT_FALSE(ParseUrl("stun:[1:2:3:4:5:6:7:8]junk:1000"));
184   EXPECT_FALSE(ParseUrl("stun::5555"));
185   EXPECT_FALSE(ParseUrl("stun:"));
186   // Test illegal URLs according to RFC 3986 (URI generic syntax)
187   // and RFC 7064 (URI schemes for STUN and TURN)
188   EXPECT_FALSE(ParseUrl("stun:/hostname"));  // / is not allowed
189   EXPECT_FALSE(ParseUrl("stun:?hostname"));  // ? is not allowed
190   EXPECT_FALSE(ParseUrl("stun:#hostname"));  // # is not allowed
191 }
192 
193 // Test parsing the "?transport=xxx" part of the URL.
TEST_F(IceServerParsingTest,ParseTransport)194 TEST_F(IceServerParsingTest, ParseTransport) {
195   EXPECT_TRUE(ParseTurnUrl("turn:hostname:1234?transport=tcp"));
196   EXPECT_EQ(1U, turn_servers_.size());
197   EXPECT_EQ(cricket::PROTO_TCP, turn_servers_[0].ports[0].proto);
198 
199   EXPECT_TRUE(ParseTurnUrl("turn:hostname?transport=udp"));
200   EXPECT_EQ(1U, turn_servers_.size());
201   EXPECT_EQ(cricket::PROTO_UDP, turn_servers_[0].ports[0].proto);
202 
203   EXPECT_FALSE(ParseTurnUrl("turn:hostname?transport=invalid"));
204   EXPECT_FALSE(ParseTurnUrl("turn:hostname?transport="));
205   EXPECT_FALSE(ParseTurnUrl("turn:hostname?="));
206   EXPECT_FALSE(ParseTurnUrl("turn:hostname?"));
207   EXPECT_FALSE(ParseTurnUrl("?"));
208 }
209 
210 // Reject pre-RFC 7065 syntax with ICE username contained in URL.
TEST_F(IceServerParsingTest,ParseRejectsUsername)211 TEST_F(IceServerParsingTest, ParseRejectsUsername) {
212   EXPECT_FALSE(ParseTurnUrl("turn:user@hostname"));
213 }
214 
215 // Test that username and password from IceServer is copied into the resulting
216 // RelayServerConfig.
TEST_F(IceServerParsingTest,CopyUsernameAndPasswordFromIceServer)217 TEST_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.
TEST_F(IceServerParsingTest,ParseMultipleUrls)225 TEST_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_TRUE(
234       webrtc::ParseIceServersOrError(servers, &stun_servers_, &turn_servers_)
235           .ok());
236   EXPECT_EQ(1U, stun_servers_.size());
237   EXPECT_EQ(1U, turn_servers_.size());
238 }
239 
240 }  // namespace webrtc
241