• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * libjingle
3  * Copyright 2012, 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/base/asynctcpsocket.h"
29 #include "talk/base/buffer.h"
30 #include "talk/base/dscp.h"
31 #include "talk/base/firewallsocketserver.h"
32 #include "talk/base/logging.h"
33 #include "talk/base/gunit.h"
34 #include "talk/base/helpers.h"
35 #include "talk/base/physicalsocketserver.h"
36 #include "talk/base/scoped_ptr.h"
37 #include "talk/base/socketaddress.h"
38 #include "talk/base/thread.h"
39 #include "talk/base/virtualsocketserver.h"
40 #include "talk/p2p/base/basicpacketsocketfactory.h"
41 #include "talk/p2p/base/constants.h"
42 #include "talk/p2p/base/tcpport.h"
43 #include "talk/p2p/base/testturnserver.h"
44 #include "talk/p2p/base/turnport.h"
45 #include "talk/p2p/base/udpport.h"
46 
47 using talk_base::SocketAddress;
48 using cricket::Connection;
49 using cricket::Port;
50 using cricket::PortInterface;
51 using cricket::TurnPort;
52 using cricket::UDPPort;
53 
54 static const SocketAddress kLocalAddr1("11.11.11.11", 0);
55 static const SocketAddress kLocalAddr2("22.22.22.22", 0);
56 static const SocketAddress kLocalIPv6Addr(
57     "2401:fa00:4:1000:be30:5bff:fee5:c3", 0);
58 static const SocketAddress kTurnUdpIntAddr("99.99.99.3",
59                                            cricket::TURN_SERVER_PORT);
60 static const SocketAddress kTurnTcpIntAddr("99.99.99.4",
61                                            cricket::TURN_SERVER_PORT);
62 static const SocketAddress kTurnUdpExtAddr("99.99.99.5", 0);
63 static const SocketAddress kTurnUdpIPv6IntAddr(
64     "2400:4030:1:2c00:be30:abcd:efab:cdef", cricket::TURN_SERVER_PORT);
65 static const SocketAddress kTurnUdpIPv6ExtAddr(
66   "2620:0:1000:1b03:2e41:38ff:fea6:f2a4", 0);
67 
68 static const char kIceUfrag1[] = "TESTICEUFRAG0001";
69 static const char kIceUfrag2[] = "TESTICEUFRAG0002";
70 static const char kIcePwd1[] = "TESTICEPWD00000000000001";
71 static const char kIcePwd2[] = "TESTICEPWD00000000000002";
72 static const char kTurnUsername[] = "test";
73 static const char kTurnPassword[] = "test";
74 static const int kTimeout = 1000;
75 
76 static const cricket::ProtocolAddress kTurnUdpProtoAddr(
77     kTurnUdpIntAddr, cricket::PROTO_UDP);
78 static const cricket::ProtocolAddress kTurnTcpProtoAddr(
79     kTurnTcpIntAddr, cricket::PROTO_TCP);
80 static const cricket::ProtocolAddress kTurnUdpIPv6ProtoAddr(
81     kTurnUdpIPv6IntAddr, cricket::PROTO_UDP);
82 
83 class TurnPortTest : public testing::Test,
84                      public sigslot::has_slots<> {
85  public:
TurnPortTest()86   TurnPortTest()
87       : main_(talk_base::Thread::Current()),
88         pss_(new talk_base::PhysicalSocketServer),
89         ss_(new talk_base::VirtualSocketServer(pss_.get())),
90         ss_scope_(ss_.get()),
91         network_("unittest", "unittest", talk_base::IPAddress(INADDR_ANY), 32),
92         socket_factory_(talk_base::Thread::Current()),
93         turn_server_(main_, kTurnUdpIntAddr, kTurnUdpExtAddr),
94         turn_ready_(false),
95         turn_error_(false),
96         turn_unknown_address_(false),
97         turn_create_permission_success_(false),
98         udp_ready_(false) {
99     network_.AddIP(talk_base::IPAddress(INADDR_ANY));
100   }
101 
OnTurnPortComplete(Port * port)102   void OnTurnPortComplete(Port* port) {
103     turn_ready_ = true;
104   }
OnTurnPortError(Port * port)105   void OnTurnPortError(Port* port) {
106     turn_error_ = true;
107   }
OnTurnUnknownAddress(PortInterface * port,const SocketAddress & addr,cricket::ProtocolType proto,cricket::IceMessage * msg,const std::string & rf,bool)108   void OnTurnUnknownAddress(PortInterface* port, const SocketAddress& addr,
109                             cricket::ProtocolType proto,
110                             cricket::IceMessage* msg, const std::string& rf,
111                             bool /*port_muxed*/) {
112     turn_unknown_address_ = true;
113   }
OnTurnCreatePermissionResult(TurnPort * port,const SocketAddress & addr,int code)114   void OnTurnCreatePermissionResult(TurnPort* port, const SocketAddress& addr,
115                                      int code) {
116     // Ignoring the address.
117     if (code == 0) {
118       turn_create_permission_success_ = true;
119     }
120   }
OnTurnReadPacket(Connection * conn,const char * data,size_t size,const talk_base::PacketTime & packet_time)121   void OnTurnReadPacket(Connection* conn, const char* data, size_t size,
122                         const talk_base::PacketTime& packet_time) {
123     turn_packets_.push_back(talk_base::Buffer(data, size));
124   }
OnUdpPortComplete(Port * port)125   void OnUdpPortComplete(Port* port) {
126     udp_ready_ = true;
127   }
OnUdpReadPacket(Connection * conn,const char * data,size_t size,const talk_base::PacketTime & packet_time)128   void OnUdpReadPacket(Connection* conn, const char* data, size_t size,
129                        const talk_base::PacketTime& packet_time) {
130     udp_packets_.push_back(talk_base::Buffer(data, size));
131   }
132 
CreateServerSocket(const SocketAddress addr)133   talk_base::AsyncSocket* CreateServerSocket(const SocketAddress addr) {
134     talk_base::AsyncSocket* socket = ss_->CreateAsyncSocket(SOCK_STREAM);
135     EXPECT_GE(socket->Bind(addr), 0);
136     EXPECT_GE(socket->Listen(5), 0);
137     return socket;
138   }
139 
CreateTurnPort(const std::string & username,const std::string & password,const cricket::ProtocolAddress & server_address)140   void CreateTurnPort(const std::string& username,
141                       const std::string& password,
142                       const cricket::ProtocolAddress& server_address) {
143     CreateTurnPort(kLocalAddr1, username, password, server_address);
144   }
CreateTurnPort(const talk_base::SocketAddress & local_address,const std::string & username,const std::string & password,const cricket::ProtocolAddress & server_address)145   void CreateTurnPort(const talk_base::SocketAddress& local_address,
146                       const std::string& username,
147                       const std::string& password,
148                       const cricket::ProtocolAddress& server_address) {
149     cricket::RelayCredentials credentials(username, password);
150     turn_port_.reset(TurnPort::Create(main_, &socket_factory_, &network_,
151                                  local_address.ipaddr(), 0, 0,
152                                  kIceUfrag1, kIcePwd1,
153                                  server_address, credentials));
154     turn_port_->SignalPortComplete.connect(this,
155         &TurnPortTest::OnTurnPortComplete);
156     turn_port_->SignalPortError.connect(this,
157         &TurnPortTest::OnTurnPortError);
158     turn_port_->SignalUnknownAddress.connect(this,
159         &TurnPortTest::OnTurnUnknownAddress);
160     turn_port_->SignalCreatePermissionResult.connect(this,
161         &TurnPortTest::OnTurnCreatePermissionResult);
162   }
CreateUdpPort()163   void CreateUdpPort() {
164     udp_port_.reset(UDPPort::Create(main_, &socket_factory_, &network_,
165                                     kLocalAddr2.ipaddr(), 0, 0,
166                                     kIceUfrag2, kIcePwd2));
167     udp_port_->SignalPortComplete.connect(
168         this, &TurnPortTest::OnUdpPortComplete);
169   }
170 
TestTurnConnection()171   void TestTurnConnection() {
172     // Create ports and prepare addresses.
173     ASSERT_TRUE(turn_port_ != NULL);
174     turn_port_->PrepareAddress();
175     ASSERT_TRUE_WAIT(turn_ready_, kTimeout);
176     CreateUdpPort();
177     udp_port_->PrepareAddress();
178     ASSERT_TRUE_WAIT(udp_ready_, kTimeout);
179 
180     // Send ping from UDP to TURN.
181     Connection* conn1 = udp_port_->CreateConnection(
182                     turn_port_->Candidates()[0], Port::ORIGIN_MESSAGE);
183     ASSERT_TRUE(conn1 != NULL);
184     conn1->Ping(0);
185     WAIT(!turn_unknown_address_, kTimeout);
186     EXPECT_FALSE(turn_unknown_address_);
187     EXPECT_EQ(Connection::STATE_READ_INIT, conn1->read_state());
188     EXPECT_EQ(Connection::STATE_WRITE_INIT, conn1->write_state());
189 
190     // Send ping from TURN to UDP.
191     Connection* conn2 = turn_port_->CreateConnection(
192                     udp_port_->Candidates()[0], Port::ORIGIN_MESSAGE);
193     ASSERT_TRUE(conn2 != NULL);
194     ASSERT_TRUE_WAIT(turn_create_permission_success_, kTimeout);
195     conn2->Ping(0);
196 
197     EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, conn2->write_state(), kTimeout);
198     EXPECT_EQ(Connection::STATE_READABLE, conn1->read_state());
199     EXPECT_EQ(Connection::STATE_READ_INIT, conn2->read_state());
200     EXPECT_EQ(Connection::STATE_WRITE_INIT, conn1->write_state());
201 
202     // Send another ping from UDP to TURN.
203     conn1->Ping(0);
204     EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, conn1->write_state(), kTimeout);
205     EXPECT_EQ(Connection::STATE_READABLE, conn2->read_state());
206   }
207 
TestTurnSendData()208   void TestTurnSendData() {
209     turn_port_->PrepareAddress();
210     EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
211     CreateUdpPort();
212     udp_port_->PrepareAddress();
213     EXPECT_TRUE_WAIT(udp_ready_, kTimeout);
214     // Create connections and send pings.
215     Connection* conn1 = turn_port_->CreateConnection(
216         udp_port_->Candidates()[0], Port::ORIGIN_MESSAGE);
217     Connection* conn2 = udp_port_->CreateConnection(
218         turn_port_->Candidates()[0], Port::ORIGIN_MESSAGE);
219     ASSERT_TRUE(conn1 != NULL);
220     ASSERT_TRUE(conn2 != NULL);
221     conn1->SignalReadPacket.connect(static_cast<TurnPortTest*>(this),
222                                     &TurnPortTest::OnTurnReadPacket);
223     conn2->SignalReadPacket.connect(static_cast<TurnPortTest*>(this),
224                                     &TurnPortTest::OnUdpReadPacket);
225     conn1->Ping(0);
226     EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, conn1->write_state(), kTimeout);
227     conn2->Ping(0);
228     EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, conn2->write_state(), kTimeout);
229 
230     // Send some data.
231     size_t num_packets = 256;
232     for (size_t i = 0; i < num_packets; ++i) {
233       char buf[256];
234       for (size_t j = 0; j < i + 1; ++j) {
235         buf[j] = 0xFF - j;
236       }
237       conn1->Send(buf, i + 1, talk_base::DSCP_NO_CHANGE);
238       conn2->Send(buf, i + 1, talk_base::DSCP_NO_CHANGE);
239       main_->ProcessMessages(0);
240     }
241 
242     // Check the data.
243     ASSERT_EQ_WAIT(num_packets, turn_packets_.size(), kTimeout);
244     ASSERT_EQ_WAIT(num_packets, udp_packets_.size(), kTimeout);
245     for (size_t i = 0; i < num_packets; ++i) {
246       EXPECT_EQ(i + 1, turn_packets_[i].length());
247       EXPECT_EQ(i + 1, udp_packets_[i].length());
248       EXPECT_EQ(turn_packets_[i], udp_packets_[i]);
249     }
250   }
251 
252  protected:
253   talk_base::Thread* main_;
254   talk_base::scoped_ptr<talk_base::PhysicalSocketServer> pss_;
255   talk_base::scoped_ptr<talk_base::VirtualSocketServer> ss_;
256   talk_base::SocketServerScope ss_scope_;
257   talk_base::Network network_;
258   talk_base::BasicPacketSocketFactory socket_factory_;
259   cricket::TestTurnServer turn_server_;
260   talk_base::scoped_ptr<TurnPort> turn_port_;
261   talk_base::scoped_ptr<UDPPort> udp_port_;
262   bool turn_ready_;
263   bool turn_error_;
264   bool turn_unknown_address_;
265   bool turn_create_permission_success_;
266   bool udp_ready_;
267   std::vector<talk_base::Buffer> turn_packets_;
268   std::vector<talk_base::Buffer> udp_packets_;
269 };
270 
271 // Do a normal TURN allocation.
TEST_F(TurnPortTest,TestTurnAllocate)272 TEST_F(TurnPortTest, TestTurnAllocate) {
273   CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
274   EXPECT_EQ(0, turn_port_->SetOption(talk_base::Socket::OPT_SNDBUF, 10*1024));
275   turn_port_->PrepareAddress();
276   EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
277   ASSERT_EQ(1U, turn_port_->Candidates().size());
278   EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
279             turn_port_->Candidates()[0].address().ipaddr());
280   EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
281 }
282 
TEST_F(TurnPortTest,TestTurnTcpAllocate)283 TEST_F(TurnPortTest, TestTurnTcpAllocate) {
284   turn_server_.AddInternalSocket(kTurnTcpIntAddr, cricket::PROTO_TCP);
285   CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
286   EXPECT_EQ(0, turn_port_->SetOption(talk_base::Socket::OPT_SNDBUF, 10*1024));
287   turn_port_->PrepareAddress();
288   EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
289   ASSERT_EQ(1U, turn_port_->Candidates().size());
290   EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
291             turn_port_->Candidates()[0].address().ipaddr());
292   EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
293 }
294 
295 // Try to do a TURN allocation with an invalid password.
TEST_F(TurnPortTest,TestTurnAllocateBadPassword)296 TEST_F(TurnPortTest, TestTurnAllocateBadPassword) {
297   CreateTurnPort(kTurnUsername, "bad", kTurnUdpProtoAddr);
298   turn_port_->PrepareAddress();
299   EXPECT_TRUE_WAIT(turn_error_, kTimeout);
300   ASSERT_EQ(0U, turn_port_->Candidates().size());
301 }
302 
303 // Do a TURN allocation and try to send a packet to it from the outside.
304 // The packet should be dropped. Then, try to send a packet from TURN to the
305 // outside. It should reach its destination. Finally, try again from the
306 // outside. It should now work as well.
TEST_F(TurnPortTest,TestTurnConnection)307 TEST_F(TurnPortTest, TestTurnConnection) {
308   CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
309   TestTurnConnection();
310 }
311 
312 // Test that we can establish a TCP connection with TURN server.
TEST_F(TurnPortTest,TestTurnTcpConnection)313 TEST_F(TurnPortTest, TestTurnTcpConnection) {
314   turn_server_.AddInternalSocket(kTurnTcpIntAddr, cricket::PROTO_TCP);
315   CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
316   TestTurnConnection();
317 }
318 
319 // Test that we fail to create a connection when we want to use TLS over TCP.
320 // This test should be removed once we have TLS support.
TEST_F(TurnPortTest,TestTurnTlsTcpConnectionFails)321 TEST_F(TurnPortTest, TestTurnTlsTcpConnectionFails) {
322   cricket::ProtocolAddress secure_addr(kTurnTcpProtoAddr.address,
323                                        kTurnTcpProtoAddr.proto,
324                                        true);
325   CreateTurnPort(kTurnUsername, kTurnPassword, secure_addr);
326   turn_port_->PrepareAddress();
327   EXPECT_TRUE_WAIT(turn_error_, kTimeout);
328   ASSERT_EQ(0U, turn_port_->Candidates().size());
329 }
330 
331 // Run TurnConnectionTest with one-time-use nonce feature.
332 // Here server will send a 438 STALE_NONCE error message for
333 // every TURN transaction.
TEST_F(TurnPortTest,TestTurnConnectionUsingOTUNonce)334 TEST_F(TurnPortTest, TestTurnConnectionUsingOTUNonce) {
335   turn_server_.set_enable_otu_nonce(true);
336   CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
337   TestTurnConnection();
338 }
339 
340 // Do a TURN allocation, establish a UDP connection, and send some data.
TEST_F(TurnPortTest,TestTurnSendDataTurnUdpToUdp)341 TEST_F(TurnPortTest, TestTurnSendDataTurnUdpToUdp) {
342   // Create ports and prepare addresses.
343   CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
344   TestTurnSendData();
345 }
346 
347 // Do a TURN allocation, establish a TCP connection, and send some data.
TEST_F(TurnPortTest,TestTurnSendDataTurnTcpToUdp)348 TEST_F(TurnPortTest, TestTurnSendDataTurnTcpToUdp) {
349   turn_server_.AddInternalSocket(kTurnTcpIntAddr, cricket::PROTO_TCP);
350   // Create ports and prepare addresses.
351   CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
352   TestTurnSendData();
353 }
354 
355 // Test TURN fails to make a connection from IPv6 address to a server which has
356 // IPv4 address.
TEST_F(TurnPortTest,TestTurnLocalIPv6AddressServerIPv4)357 TEST_F(TurnPortTest, TestTurnLocalIPv6AddressServerIPv4) {
358   turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, cricket::PROTO_UDP);
359   CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
360                  kTurnUdpProtoAddr);
361   turn_port_->PrepareAddress();
362   ASSERT_TRUE_WAIT(turn_error_, kTimeout);
363   EXPECT_TRUE(turn_port_->Candidates().empty());
364 }
365 
366 // Test TURN make a connection from IPv6 address to a server which has
367 // IPv6 intenal address. But in this test external address is a IPv4 address,
368 // hence allocated address will be a IPv4 address.
TEST_F(TurnPortTest,TestTurnLocalIPv6AddressServerIPv6ExtenalIPv4)369 TEST_F(TurnPortTest, TestTurnLocalIPv6AddressServerIPv6ExtenalIPv4) {
370   turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, cricket::PROTO_UDP);
371   CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
372                  kTurnUdpIPv6ProtoAddr);
373   turn_port_->PrepareAddress();
374   EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
375   ASSERT_EQ(1U, turn_port_->Candidates().size());
376   EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
377             turn_port_->Candidates()[0].address().ipaddr());
378   EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
379 }
380 
381