1/* 2 * libjingle 3 * Copyright 2011 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#include "talk/p2p/base/constants.h" 29#include "talk/p2p/base/fakesession.h" 30#include "talk/p2p/base/p2ptransport.h" 31#include "talk/p2p/base/parsing.h" 32#include "talk/p2p/base/rawtransport.h" 33#include "talk/p2p/base/sessionmessages.h" 34#include "webrtc/libjingle/xmllite/xmlelement.h" 35#include "talk/xmpp/constants.h" 36#include "webrtc/base/fakesslidentity.h" 37#include "webrtc/base/gunit.h" 38#include "webrtc/base/thread.h" 39 40using cricket::Candidate; 41using cricket::Candidates; 42using cricket::Transport; 43using cricket::FakeTransport; 44using cricket::TransportChannel; 45using cricket::FakeTransportChannel; 46using cricket::IceRole; 47using cricket::TransportDescription; 48using cricket::WriteError; 49using cricket::ParseError; 50using rtc::SocketAddress; 51 52static const char kIceUfrag1[] = "TESTICEUFRAG0001"; 53static const char kIcePwd1[] = "TESTICEPWD00000000000001"; 54 55static const char kIceUfrag2[] = "TESTICEUFRAG0002"; 56static const char kIcePwd2[] = "TESTICEPWD00000000000002"; 57 58class TransportTest : public testing::Test, 59 public sigslot::has_slots<> { 60 public: 61 TransportTest() 62 : thread_(rtc::Thread::Current()), 63 transport_(new FakeTransport( 64 thread_, thread_, "test content name", NULL)), 65 channel_(NULL), 66 connecting_signalled_(false), 67 completed_(false), 68 failed_(false) { 69 transport_->SignalConnecting.connect(this, &TransportTest::OnConnecting); 70 transport_->SignalCompleted.connect(this, &TransportTest::OnCompleted); 71 transport_->SignalFailed.connect(this, &TransportTest::OnFailed); 72 } 73 ~TransportTest() { 74 transport_->DestroyAllChannels(); 75 } 76 bool SetupChannel() { 77 channel_ = CreateChannel(1); 78 return (channel_ != NULL); 79 } 80 FakeTransportChannel* CreateChannel(int component) { 81 return static_cast<FakeTransportChannel*>( 82 transport_->CreateChannel(component)); 83 } 84 void DestroyChannel() { 85 transport_->DestroyChannel(1); 86 channel_ = NULL; 87 } 88 89 protected: 90 void OnConnecting(Transport* transport) { 91 connecting_signalled_ = true; 92 } 93 void OnCompleted(Transport* transport) { 94 completed_ = true; 95 } 96 void OnFailed(Transport* transport) { 97 failed_ = true; 98 } 99 100 rtc::Thread* thread_; 101 rtc::scoped_ptr<FakeTransport> transport_; 102 FakeTransportChannel* channel_; 103 bool connecting_signalled_; 104 bool completed_; 105 bool failed_; 106}; 107 108class FakeCandidateTranslator : public cricket::CandidateTranslator { 109 public: 110 void AddMapping(int component, const std::string& channel_name) { 111 name_to_component[channel_name] = component; 112 component_to_name[component] = channel_name; 113 } 114 115 bool GetChannelNameFromComponent( 116 int component, std::string* channel_name) const { 117 if (component_to_name.find(component) == component_to_name.end()) { 118 return false; 119 } 120 *channel_name = component_to_name.find(component)->second; 121 return true; 122 } 123 bool GetComponentFromChannelName( 124 const std::string& channel_name, int* component) const { 125 if (name_to_component.find(channel_name) == name_to_component.end()) { 126 return false; 127 } 128 *component = name_to_component.find(channel_name)->second; 129 return true; 130 } 131 132 std::map<std::string, int> name_to_component; 133 std::map<int, std::string> component_to_name; 134}; 135 136// Test that calling ConnectChannels triggers an OnConnecting signal. 137TEST_F(TransportTest, TestConnectChannelsDoesSignal) { 138 EXPECT_TRUE(SetupChannel()); 139 transport_->ConnectChannels(); 140 EXPECT_FALSE(connecting_signalled_); 141 142 EXPECT_TRUE_WAIT(connecting_signalled_, 100); 143} 144 145// Test that DestroyAllChannels kills any pending OnConnecting signals. 146TEST_F(TransportTest, TestDestroyAllClearsPosts) { 147 EXPECT_TRUE(transport_->CreateChannel(1) != NULL); 148 149 transport_->ConnectChannels(); 150 transport_->DestroyAllChannels(); 151 152 thread_->ProcessMessages(0); 153 EXPECT_FALSE(connecting_signalled_); 154} 155 156// This test verifies channels are created with proper ICE 157// role, tiebreaker and remote ice mode and credentials after offer and 158// answer negotiations. 159TEST_F(TransportTest, TestChannelIceParameters) { 160 transport_->SetIceRole(cricket::ICEROLE_CONTROLLING); 161 transport_->SetIceTiebreaker(99U); 162 cricket::TransportDescription local_desc( 163 cricket::NS_JINGLE_ICE_UDP, kIceUfrag1, kIcePwd1); 164 ASSERT_TRUE(transport_->SetLocalTransportDescription(local_desc, 165 cricket::CA_OFFER, 166 NULL)); 167 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, transport_->ice_role()); 168 EXPECT_TRUE(SetupChannel()); 169 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel_->GetIceRole()); 170 EXPECT_EQ(cricket::ICEMODE_FULL, channel_->remote_ice_mode()); 171 EXPECT_EQ(kIceUfrag1, channel_->ice_ufrag()); 172 EXPECT_EQ(kIcePwd1, channel_->ice_pwd()); 173 174 cricket::TransportDescription remote_desc( 175 cricket::NS_JINGLE_ICE_UDP, kIceUfrag1, kIcePwd1); 176 ASSERT_TRUE(transport_->SetRemoteTransportDescription(remote_desc, 177 cricket::CA_ANSWER, 178 NULL)); 179 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel_->GetIceRole()); 180 EXPECT_EQ(99U, channel_->IceTiebreaker()); 181 EXPECT_EQ(cricket::ICEMODE_FULL, channel_->remote_ice_mode()); 182 // Changing the transport role from CONTROLLING to CONTROLLED. 183 transport_->SetIceRole(cricket::ICEROLE_CONTROLLED); 184 EXPECT_EQ(cricket::ICEROLE_CONTROLLED, channel_->GetIceRole()); 185 EXPECT_EQ(cricket::ICEMODE_FULL, channel_->remote_ice_mode()); 186 EXPECT_EQ(kIceUfrag1, channel_->remote_ice_ufrag()); 187 EXPECT_EQ(kIcePwd1, channel_->remote_ice_pwd()); 188} 189 190// Verifies that IceCredentialsChanged returns true when either ufrag or pwd 191// changed, and false in other cases. 192TEST_F(TransportTest, TestIceCredentialsChanged) { 193 EXPECT_TRUE(cricket::IceCredentialsChanged("u1", "p1", "u2", "p2")); 194 EXPECT_TRUE(cricket::IceCredentialsChanged("u1", "p1", "u2", "p1")); 195 EXPECT_TRUE(cricket::IceCredentialsChanged("u1", "p1", "u1", "p2")); 196 EXPECT_FALSE(cricket::IceCredentialsChanged("u1", "p1", "u1", "p1")); 197} 198 199// This test verifies that the callee's ICE role changes from controlled to 200// controlling when the callee triggers an ICE restart. 201TEST_F(TransportTest, TestIceControlledToControllingOnIceRestart) { 202 EXPECT_TRUE(SetupChannel()); 203 transport_->SetIceRole(cricket::ICEROLE_CONTROLLED); 204 205 cricket::TransportDescription desc( 206 cricket::NS_JINGLE_ICE_UDP, kIceUfrag1, kIcePwd1); 207 ASSERT_TRUE(transport_->SetRemoteTransportDescription(desc, 208 cricket::CA_OFFER, 209 NULL)); 210 ASSERT_TRUE(transport_->SetLocalTransportDescription(desc, 211 cricket::CA_ANSWER, 212 NULL)); 213 EXPECT_EQ(cricket::ICEROLE_CONTROLLED, transport_->ice_role()); 214 215 cricket::TransportDescription new_local_desc( 216 cricket::NS_JINGLE_ICE_UDP, kIceUfrag2, kIcePwd2); 217 ASSERT_TRUE(transport_->SetLocalTransportDescription(new_local_desc, 218 cricket::CA_OFFER, 219 NULL)); 220 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, transport_->ice_role()); 221 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel_->GetIceRole()); 222} 223 224// This test verifies that the caller's ICE role changes from controlling to 225// controlled when the callee triggers an ICE restart. 226TEST_F(TransportTest, TestIceControllingToControlledOnIceRestart) { 227 EXPECT_TRUE(SetupChannel()); 228 transport_->SetIceRole(cricket::ICEROLE_CONTROLLING); 229 230 cricket::TransportDescription desc( 231 cricket::NS_JINGLE_ICE_UDP, kIceUfrag1, kIcePwd1); 232 ASSERT_TRUE(transport_->SetLocalTransportDescription(desc, 233 cricket::CA_OFFER, 234 NULL)); 235 ASSERT_TRUE(transport_->SetRemoteTransportDescription(desc, 236 cricket::CA_ANSWER, 237 NULL)); 238 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, transport_->ice_role()); 239 240 cricket::TransportDescription new_local_desc( 241 cricket::NS_JINGLE_ICE_UDP, kIceUfrag2, kIcePwd2); 242 ASSERT_TRUE(transport_->SetLocalTransportDescription(new_local_desc, 243 cricket::CA_ANSWER, 244 NULL)); 245 EXPECT_EQ(cricket::ICEROLE_CONTROLLED, transport_->ice_role()); 246 EXPECT_EQ(cricket::ICEROLE_CONTROLLED, channel_->GetIceRole()); 247} 248 249// This test verifies that the caller's ICE role is still controlling after the 250// callee triggers ICE restart if the callee's ICE mode is LITE. 251TEST_F(TransportTest, TestIceControllingOnIceRestartIfRemoteIsIceLite) { 252 EXPECT_TRUE(SetupChannel()); 253 transport_->SetIceRole(cricket::ICEROLE_CONTROLLING); 254 255 cricket::TransportDescription desc( 256 cricket::NS_JINGLE_ICE_UDP, kIceUfrag1, kIcePwd1); 257 ASSERT_TRUE(transport_->SetLocalTransportDescription(desc, 258 cricket::CA_OFFER, 259 NULL)); 260 261 cricket::TransportDescription remote_desc( 262 cricket::NS_JINGLE_ICE_UDP, std::vector<std::string>(), 263 kIceUfrag1, kIcePwd1, cricket::ICEMODE_LITE, 264 cricket::CONNECTIONROLE_NONE, NULL, cricket::Candidates()); 265 ASSERT_TRUE(transport_->SetRemoteTransportDescription(remote_desc, 266 cricket::CA_ANSWER, 267 NULL)); 268 269 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, transport_->ice_role()); 270 271 cricket::TransportDescription new_local_desc( 272 cricket::NS_JINGLE_ICE_UDP, kIceUfrag2, kIcePwd2); 273 ASSERT_TRUE(transport_->SetLocalTransportDescription(new_local_desc, 274 cricket::CA_ANSWER, 275 NULL)); 276 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, transport_->ice_role()); 277 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel_->GetIceRole()); 278} 279 280// This test verifies that the Completed and Failed states can be reached. 281TEST_F(TransportTest, TestChannelCompletedAndFailed) { 282 transport_->SetIceRole(cricket::ICEROLE_CONTROLLING); 283 cricket::TransportDescription local_desc( 284 cricket::NS_JINGLE_ICE_UDP, kIceUfrag1, kIcePwd1); 285 ASSERT_TRUE(transport_->SetLocalTransportDescription(local_desc, 286 cricket::CA_OFFER, 287 NULL)); 288 EXPECT_TRUE(SetupChannel()); 289 290 cricket::TransportDescription remote_desc( 291 cricket::NS_JINGLE_ICE_UDP, kIceUfrag1, kIcePwd1); 292 ASSERT_TRUE(transport_->SetRemoteTransportDescription(remote_desc, 293 cricket::CA_ANSWER, 294 NULL)); 295 296 channel_->SetConnectionCount(2); 297 channel_->SignalCandidatesAllocationDone(channel_); 298 channel_->SetWritable(true); 299 EXPECT_TRUE_WAIT(transport_->all_channels_writable(), 100); 300 // ICE is not yet completed because there is still more than one connection. 301 EXPECT_FALSE(completed_); 302 EXPECT_FALSE(failed_); 303 304 // When the connection count drops to 1, SignalCompleted should be emitted, 305 // and completed() should be true. 306 channel_->SetConnectionCount(1); 307 EXPECT_TRUE_WAIT(completed_, 100); 308 completed_ = false; 309 310 // When the connection count drops to 0, SignalFailed should be emitted, and 311 // completed() should be false. 312 channel_->SetConnectionCount(0); 313 EXPECT_TRUE_WAIT(failed_, 100); 314 EXPECT_FALSE(completed_); 315} 316 317// Tests channel role is reversed after receiving ice-lite from remote. 318TEST_F(TransportTest, TestSetRemoteIceLiteInOffer) { 319 transport_->SetIceRole(cricket::ICEROLE_CONTROLLED); 320 cricket::TransportDescription remote_desc( 321 cricket::NS_JINGLE_ICE_UDP, std::vector<std::string>(), 322 kIceUfrag1, kIcePwd1, cricket::ICEMODE_LITE, 323 cricket::CONNECTIONROLE_ACTPASS, NULL, cricket::Candidates()); 324 ASSERT_TRUE(transport_->SetRemoteTransportDescription(remote_desc, 325 cricket::CA_OFFER, 326 NULL)); 327 cricket::TransportDescription local_desc( 328 cricket::NS_JINGLE_ICE_UDP, kIceUfrag1, kIcePwd1); 329 ASSERT_TRUE(transport_->SetLocalTransportDescription(local_desc, 330 cricket::CA_ANSWER, 331 NULL)); 332 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, transport_->ice_role()); 333 EXPECT_TRUE(SetupChannel()); 334 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel_->GetIceRole()); 335 EXPECT_EQ(cricket::ICEMODE_LITE, channel_->remote_ice_mode()); 336} 337 338// Tests ice-lite in remote answer. 339TEST_F(TransportTest, TestSetRemoteIceLiteInAnswer) { 340 transport_->SetIceRole(cricket::ICEROLE_CONTROLLING); 341 cricket::TransportDescription local_desc( 342 cricket::NS_JINGLE_ICE_UDP, kIceUfrag1, kIcePwd1); 343 ASSERT_TRUE(transport_->SetLocalTransportDescription(local_desc, 344 cricket::CA_OFFER, 345 NULL)); 346 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, transport_->ice_role()); 347 EXPECT_TRUE(SetupChannel()); 348 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel_->GetIceRole()); 349 // Channels will be created in ICEFULL_MODE. 350 EXPECT_EQ(cricket::ICEMODE_FULL, channel_->remote_ice_mode()); 351 cricket::TransportDescription remote_desc( 352 cricket::NS_JINGLE_ICE_UDP, std::vector<std::string>(), 353 kIceUfrag1, kIcePwd1, cricket::ICEMODE_LITE, 354 cricket::CONNECTIONROLE_NONE, NULL, cricket::Candidates()); 355 ASSERT_TRUE(transport_->SetRemoteTransportDescription(remote_desc, 356 cricket::CA_ANSWER, 357 NULL)); 358 EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel_->GetIceRole()); 359 // After receiving remote description with ICEMODE_LITE, channel should 360 // have mode set to ICEMODE_LITE. 361 EXPECT_EQ(cricket::ICEMODE_LITE, channel_->remote_ice_mode()); 362} 363 364// Tests that we can properly serialize/deserialize candidates. 365TEST_F(TransportTest, TestP2PTransportWriteAndParseCandidate) { 366 Candidate test_candidate( 367 "", 1, "udp", 368 rtc::SocketAddress("2001:db8:fefe::1", 9999), 369 738197504, "abcdef", "ghijkl", "foo", "testnet", 50, ""); 370 Candidate test_candidate2( 371 "", 2, "tcp", 372 rtc::SocketAddress("192.168.7.1", 9999), 373 1107296256, "mnopqr", "stuvwx", "bar", "testnet2", 100, ""); 374 rtc::SocketAddress host_address("www.google.com", 24601); 375 host_address.SetResolvedIP(rtc::IPAddress(0x0A000001)); 376 Candidate test_candidate3( 377 "", 3, "spdy", host_address, 1476395008, "yzabcd", 378 "efghij", "baz", "testnet3", 150, ""); 379 WriteError write_error; 380 ParseError parse_error; 381 rtc::scoped_ptr<buzz::XmlElement> elem; 382 cricket::Candidate parsed_candidate; 383 cricket::P2PTransportParser parser; 384 385 FakeCandidateTranslator translator; 386 translator.AddMapping(1, "test"); 387 translator.AddMapping(2, "test2"); 388 translator.AddMapping(3, "test3"); 389 390 EXPECT_TRUE(parser.WriteGingleCandidate(test_candidate, &translator, 391 elem.accept(), &write_error)); 392 EXPECT_EQ("", write_error.text); 393 EXPECT_EQ("test", elem->Attr(buzz::QN_NAME)); 394 EXPECT_EQ("udp", elem->Attr(cricket::QN_PROTOCOL)); 395 EXPECT_EQ("2001:db8:fefe::1", elem->Attr(cricket::QN_ADDRESS)); 396 EXPECT_EQ("9999", elem->Attr(cricket::QN_PORT)); 397 EXPECT_EQ("0.34", elem->Attr(cricket::QN_PREFERENCE)); 398 EXPECT_EQ("abcdef", elem->Attr(cricket::QN_USERNAME)); 399 EXPECT_EQ("ghijkl", elem->Attr(cricket::QN_PASSWORD)); 400 EXPECT_EQ("foo", elem->Attr(cricket::QN_TYPE)); 401 EXPECT_EQ("testnet", elem->Attr(cricket::QN_NETWORK)); 402 EXPECT_EQ("50", elem->Attr(cricket::QN_GENERATION)); 403 404 EXPECT_TRUE(parser.ParseGingleCandidate(elem.get(), &translator, 405 &parsed_candidate, &parse_error)); 406 EXPECT_TRUE(test_candidate.IsEquivalent(parsed_candidate)); 407 408 EXPECT_TRUE(parser.WriteGingleCandidate(test_candidate2, &translator, 409 elem.accept(), &write_error)); 410 EXPECT_EQ("test2", elem->Attr(buzz::QN_NAME)); 411 EXPECT_EQ("tcp", elem->Attr(cricket::QN_PROTOCOL)); 412 EXPECT_EQ("192.168.7.1", elem->Attr(cricket::QN_ADDRESS)); 413 EXPECT_EQ("9999", elem->Attr(cricket::QN_PORT)); 414 EXPECT_EQ("0.51", elem->Attr(cricket::QN_PREFERENCE)); 415 EXPECT_EQ("mnopqr", elem->Attr(cricket::QN_USERNAME)); 416 EXPECT_EQ("stuvwx", elem->Attr(cricket::QN_PASSWORD)); 417 EXPECT_EQ("bar", elem->Attr(cricket::QN_TYPE)); 418 EXPECT_EQ("testnet2", elem->Attr(cricket::QN_NETWORK)); 419 EXPECT_EQ("100", elem->Attr(cricket::QN_GENERATION)); 420 421 EXPECT_TRUE(parser.ParseGingleCandidate(elem.get(), &translator, 422 &parsed_candidate, &parse_error)); 423 EXPECT_TRUE(test_candidate2.IsEquivalent(parsed_candidate)); 424 425 // Check that an ip is preferred over hostname. 426 EXPECT_TRUE(parser.WriteGingleCandidate(test_candidate3, &translator, 427 elem.accept(), &write_error)); 428 EXPECT_EQ("test3", elem->Attr(cricket::QN_NAME)); 429 EXPECT_EQ("spdy", elem->Attr(cricket::QN_PROTOCOL)); 430 EXPECT_EQ("10.0.0.1", elem->Attr(cricket::QN_ADDRESS)); 431 EXPECT_EQ("24601", elem->Attr(cricket::QN_PORT)); 432 EXPECT_EQ("0.69", elem->Attr(cricket::QN_PREFERENCE)); 433 EXPECT_EQ("yzabcd", elem->Attr(cricket::QN_USERNAME)); 434 EXPECT_EQ("efghij", elem->Attr(cricket::QN_PASSWORD)); 435 EXPECT_EQ("baz", elem->Attr(cricket::QN_TYPE)); 436 EXPECT_EQ("testnet3", elem->Attr(cricket::QN_NETWORK)); 437 EXPECT_EQ("150", elem->Attr(cricket::QN_GENERATION)); 438 439 EXPECT_TRUE(parser.ParseGingleCandidate(elem.get(), &translator, 440 &parsed_candidate, &parse_error)); 441 EXPECT_TRUE(test_candidate3.IsEquivalent(parsed_candidate)); 442} 443 444TEST_F(TransportTest, TestGetStats) { 445 EXPECT_TRUE(SetupChannel()); 446 cricket::TransportStats stats; 447 EXPECT_TRUE(transport_->GetStats(&stats)); 448 // Note that this tests the behavior of a FakeTransportChannel. 449 ASSERT_EQ(1U, stats.channel_stats.size()); 450 EXPECT_EQ(1, stats.channel_stats[0].component); 451 transport_->ConnectChannels(); 452 EXPECT_TRUE(transport_->GetStats(&stats)); 453 ASSERT_EQ(1U, stats.channel_stats.size()); 454 EXPECT_EQ(1, stats.channel_stats[0].component); 455} 456