blob: fc6d48c9a5d82991583182fe80e276a66d77d757 [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
2 * libjingle
3 * Copyright 2004 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/crc32.h"
29#include "talk/base/gunit.h"
30#include "talk/base/helpers.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000031#include "talk/base/logging.h"
32#include "talk/base/natserver.h"
33#include "talk/base/natsocketfactory.h"
34#include "talk/base/physicalsocketserver.h"
35#include "talk/base/scoped_ptr.h"
36#include "talk/base/socketaddress.h"
mallinath@webrtc.org5a59ccb2014-02-07 23:22:00 +000037#include "talk/base/ssladapter.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000038#include "talk/base/stringutils.h"
39#include "talk/base/thread.h"
40#include "talk/base/virtualsocketserver.h"
41#include "talk/p2p/base/basicpacketsocketfactory.h"
42#include "talk/p2p/base/portproxy.h"
43#include "talk/p2p/base/relayport.h"
44#include "talk/p2p/base/stunport.h"
45#include "talk/p2p/base/tcpport.h"
46#include "talk/p2p/base/testrelayserver.h"
47#include "talk/p2p/base/teststunserver.h"
48#include "talk/p2p/base/testturnserver.h"
49#include "talk/p2p/base/transport.h"
50#include "talk/p2p/base/turnport.h"
51
52using talk_base::AsyncPacketSocket;
53using talk_base::ByteBuffer;
54using talk_base::NATType;
55using talk_base::NAT_OPEN_CONE;
56using talk_base::NAT_ADDR_RESTRICTED;
57using talk_base::NAT_PORT_RESTRICTED;
58using talk_base::NAT_SYMMETRIC;
59using talk_base::PacketSocketFactory;
60using talk_base::scoped_ptr;
61using talk_base::Socket;
62using talk_base::SocketAddress;
63using namespace cricket;
64
65static const int kTimeout = 1000;
66static const SocketAddress kLocalAddr1("192.168.1.2", 0);
67static const SocketAddress kLocalAddr2("192.168.1.3", 0);
68static const SocketAddress kNatAddr1("77.77.77.77", talk_base::NAT_SERVER_PORT);
69static const SocketAddress kNatAddr2("88.88.88.88", talk_base::NAT_SERVER_PORT);
70static const SocketAddress kStunAddr("99.99.99.1", STUN_SERVER_PORT);
71static const SocketAddress kRelayUdpIntAddr("99.99.99.2", 5000);
72static const SocketAddress kRelayUdpExtAddr("99.99.99.3", 5001);
73static const SocketAddress kRelayTcpIntAddr("99.99.99.2", 5002);
74static const SocketAddress kRelayTcpExtAddr("99.99.99.3", 5003);
75static const SocketAddress kRelaySslTcpIntAddr("99.99.99.2", 5004);
76static const SocketAddress kRelaySslTcpExtAddr("99.99.99.3", 5005);
77static const SocketAddress kTurnUdpIntAddr("99.99.99.4", STUN_SERVER_PORT);
78static const SocketAddress kTurnUdpExtAddr("99.99.99.5", 0);
79static const RelayCredentials kRelayCredentials("test", "test");
80
81// TODO: Update these when RFC5245 is completely supported.
82// Magic value of 30 is from RFC3484, for IPv4 addresses.
83static const uint32 kDefaultPrflxPriority = ICE_TYPE_PREFERENCE_PRFLX << 24 |
84 30 << 8 | (256 - ICE_CANDIDATE_COMPONENT_DEFAULT);
85static const int STUN_ERROR_BAD_REQUEST_AS_GICE =
86 STUN_ERROR_BAD_REQUEST / 256 * 100 + STUN_ERROR_BAD_REQUEST % 256;
87static const int STUN_ERROR_UNAUTHORIZED_AS_GICE =
88 STUN_ERROR_UNAUTHORIZED / 256 * 100 + STUN_ERROR_UNAUTHORIZED % 256;
89static const int STUN_ERROR_SERVER_ERROR_AS_GICE =
90 STUN_ERROR_SERVER_ERROR / 256 * 100 + STUN_ERROR_SERVER_ERROR % 256;
91
92static const int kTiebreaker1 = 11111;
93static const int kTiebreaker2 = 22222;
94
95static Candidate GetCandidate(Port* port) {
96 assert(port->Candidates().size() == 1);
97 return port->Candidates()[0];
98}
99
100static SocketAddress GetAddress(Port* port) {
101 return GetCandidate(port).address();
102}
103
104static IceMessage* CopyStunMessage(const IceMessage* src) {
105 IceMessage* dst = new IceMessage();
106 ByteBuffer buf;
107 src->Write(&buf);
108 dst->Read(&buf);
109 return dst;
110}
111
112static bool WriteStunMessage(const StunMessage* msg, ByteBuffer* buf) {
113 buf->Resize(0); // clear out any existing buffer contents
114 return msg->Write(buf);
115}
116
117// Stub port class for testing STUN generation and processing.
118class TestPort : public Port {
119 public:
120 TestPort(talk_base::Thread* thread, const std::string& type,
121 talk_base::PacketSocketFactory* factory, talk_base::Network* network,
122 const talk_base::IPAddress& ip, int min_port, int max_port,
123 const std::string& username_fragment, const std::string& password)
124 : Port(thread, type, factory, network, ip,
125 min_port, max_port, username_fragment, password) {
126 }
127 ~TestPort() {}
128
129 // Expose GetStunMessage so that we can test it.
130 using cricket::Port::GetStunMessage;
131
132 // The last StunMessage that was sent on this Port.
133 // TODO: Make these const; requires changes to SendXXXXResponse.
134 ByteBuffer* last_stun_buf() { return last_stun_buf_.get(); }
135 IceMessage* last_stun_msg() { return last_stun_msg_.get(); }
136 int last_stun_error_code() {
137 int code = 0;
138 if (last_stun_msg_) {
139 const StunErrorCodeAttribute* error_attr = last_stun_msg_->GetErrorCode();
140 if (error_attr) {
141 code = error_attr->code();
142 }
143 }
144 return code;
145 }
146
147 virtual void PrepareAddress() {
148 talk_base::SocketAddress addr(ip(), min_port());
buildbot@webrtc.orgf875f152014-04-14 16:06:21 +0000149 AddAddress(addr, addr, talk_base::SocketAddress(), "udp", Type(),
150 ICE_TYPE_PREFERENCE_HOST, true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000151 }
152
153 // Exposed for testing candidate building.
154 void AddCandidateAddress(const talk_base::SocketAddress& addr) {
buildbot@webrtc.orgf875f152014-04-14 16:06:21 +0000155 AddAddress(addr, addr, talk_base::SocketAddress(), "udp", Type(),
156 type_preference_, false);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000157 }
158 void AddCandidateAddress(const talk_base::SocketAddress& addr,
159 const talk_base::SocketAddress& base_address,
160 const std::string& type,
161 int type_preference,
162 bool final) {
buildbot@webrtc.orgf875f152014-04-14 16:06:21 +0000163 AddAddress(addr, base_address, talk_base::SocketAddress(), "udp", type,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000164 type_preference, final);
165 }
166
167 virtual Connection* CreateConnection(const Candidate& remote_candidate,
168 CandidateOrigin origin) {
169 Connection* conn = new ProxyConnection(this, 0, remote_candidate);
170 AddConnection(conn);
171 // Set use-candidate attribute flag as this will add USE-CANDIDATE attribute
172 // in STUN binding requests.
173 conn->set_use_candidate_attr(true);
174 return conn;
175 }
176 virtual int SendTo(
177 const void* data, size_t size, const talk_base::SocketAddress& addr,
mallinath@webrtc.org385857d2014-02-14 00:56:12 +0000178 const talk_base::PacketOptions& options, bool payload) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000179 if (!payload) {
180 IceMessage* msg = new IceMessage;
181 ByteBuffer* buf = new ByteBuffer(static_cast<const char*>(data), size);
182 ByteBuffer::ReadPosition pos(buf->GetReadPosition());
183 if (!msg->Read(buf)) {
184 delete msg;
185 delete buf;
186 return -1;
187 }
188 buf->SetReadPosition(pos);
189 last_stun_buf_.reset(buf);
190 last_stun_msg_.reset(msg);
191 }
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000192 return static_cast<int>(size);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000193 }
194 virtual int SetOption(talk_base::Socket::Option opt, int value) {
195 return 0;
196 }
197 virtual int GetOption(talk_base::Socket::Option opt, int* value) {
198 return -1;
199 }
200 virtual int GetError() {
201 return 0;
202 }
203 void Reset() {
204 last_stun_buf_.reset();
205 last_stun_msg_.reset();
206 }
207 void set_type_preference(int type_preference) {
208 type_preference_ = type_preference;
209 }
210
211 private:
212 talk_base::scoped_ptr<ByteBuffer> last_stun_buf_;
213 talk_base::scoped_ptr<IceMessage> last_stun_msg_;
214 int type_preference_;
215};
216
217class TestChannel : public sigslot::has_slots<> {
218 public:
wu@webrtc.orgf6d6ed02014-01-03 22:08:47 +0000219 // Takes ownership of |p1| (but not |p2|).
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000220 TestChannel(Port* p1, Port* p2)
221 : ice_mode_(ICEMODE_FULL), src_(p1), dst_(p2), complete_count_(0),
wu@webrtc.org97077a32013-10-25 21:18:33 +0000222 conn_(NULL), remote_request_(), nominated_(false) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000223 src_->SignalPortComplete.connect(
224 this, &TestChannel::OnPortComplete);
225 src_->SignalUnknownAddress.connect(this, &TestChannel::OnUnknownAddress);
wu@webrtc.orgf6d6ed02014-01-03 22:08:47 +0000226 src_->SignalDestroyed.connect(this, &TestChannel::OnSrcPortDestroyed);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000227 }
228
229 int complete_count() { return complete_count_; }
230 Connection* conn() { return conn_; }
231 const SocketAddress& remote_address() { return remote_address_; }
232 const std::string remote_fragment() { return remote_frag_; }
233
234 void Start() {
235 src_->PrepareAddress();
236 }
237 void CreateConnection() {
238 conn_ = src_->CreateConnection(GetCandidate(dst_), Port::ORIGIN_MESSAGE);
239 IceMode remote_ice_mode =
240 (ice_mode_ == ICEMODE_FULL) ? ICEMODE_LITE : ICEMODE_FULL;
241 conn_->set_remote_ice_mode(remote_ice_mode);
242 conn_->set_use_candidate_attr(remote_ice_mode == ICEMODE_FULL);
243 conn_->SignalStateChange.connect(
244 this, &TestChannel::OnConnectionStateChange);
245 }
246 void OnConnectionStateChange(Connection* conn) {
247 if (conn->write_state() == Connection::STATE_WRITABLE) {
248 conn->set_use_candidate_attr(true);
249 nominated_ = true;
250 }
251 }
252 void AcceptConnection() {
253 ASSERT_TRUE(remote_request_.get() != NULL);
254 Candidate c = GetCandidate(dst_);
255 c.set_address(remote_address_);
256 conn_ = src_->CreateConnection(c, Port::ORIGIN_MESSAGE);
257 src_->SendBindingResponse(remote_request_.get(), remote_address_);
258 remote_request_.reset();
259 }
260 void Ping() {
261 Ping(0);
262 }
263 void Ping(uint32 now) {
264 conn_->Ping(now);
265 }
266 void Stop() {
267 conn_->SignalDestroyed.connect(this, &TestChannel::OnDestroyed);
268 conn_->Destroy();
269 }
270
271 void OnPortComplete(Port* port) {
272 complete_count_++;
273 }
274 void SetIceMode(IceMode ice_mode) {
275 ice_mode_ = ice_mode;
276 }
277
278 void OnUnknownAddress(PortInterface* port, const SocketAddress& addr,
279 ProtocolType proto,
280 IceMessage* msg, const std::string& rf,
281 bool /*port_muxed*/) {
282 ASSERT_EQ(src_.get(), port);
283 if (!remote_address_.IsNil()) {
284 ASSERT_EQ(remote_address_, addr);
285 }
286 // MI and PRIORITY attribute should be present in ping requests when port
287 // is in ICEPROTO_RFC5245 mode.
288 const cricket::StunUInt32Attribute* priority_attr =
289 msg->GetUInt32(STUN_ATTR_PRIORITY);
290 const cricket::StunByteStringAttribute* mi_attr =
291 msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY);
292 const cricket::StunUInt32Attribute* fingerprint_attr =
293 msg->GetUInt32(STUN_ATTR_FINGERPRINT);
294 if (src_->IceProtocol() == cricket::ICEPROTO_RFC5245) {
295 EXPECT_TRUE(priority_attr != NULL);
296 EXPECT_TRUE(mi_attr != NULL);
297 EXPECT_TRUE(fingerprint_attr != NULL);
298 } else {
299 EXPECT_TRUE(priority_attr == NULL);
300 EXPECT_TRUE(mi_attr == NULL);
301 EXPECT_TRUE(fingerprint_attr == NULL);
302 }
303 remote_address_ = addr;
304 remote_request_.reset(CopyStunMessage(msg));
305 remote_frag_ = rf;
306 }
307
308 void OnDestroyed(Connection* conn) {
309 ASSERT_EQ(conn_, conn);
310 conn_ = NULL;
311 }
312
wu@webrtc.orgf6d6ed02014-01-03 22:08:47 +0000313 void OnSrcPortDestroyed(PortInterface* port) {
314 Port* destroyed_src = src_.release();
315 ASSERT_EQ(destroyed_src, port);
316 }
317
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000318 bool nominated() const { return nominated_; }
319
320 private:
321 IceMode ice_mode_;
322 talk_base::scoped_ptr<Port> src_;
323 Port* dst_;
324
325 int complete_count_;
326 Connection* conn_;
327 SocketAddress remote_address_;
328 talk_base::scoped_ptr<StunMessage> remote_request_;
329 std::string remote_frag_;
330 bool nominated_;
331};
332
333class PortTest : public testing::Test, public sigslot::has_slots<> {
334 public:
335 PortTest()
336 : main_(talk_base::Thread::Current()),
337 pss_(new talk_base::PhysicalSocketServer),
338 ss_(new talk_base::VirtualSocketServer(pss_.get())),
339 ss_scope_(ss_.get()),
340 network_("unittest", "unittest", talk_base::IPAddress(INADDR_ANY), 32),
341 socket_factory_(talk_base::Thread::Current()),
342 nat_factory1_(ss_.get(), kNatAddr1),
343 nat_factory2_(ss_.get(), kNatAddr2),
344 nat_socket_factory1_(&nat_factory1_),
345 nat_socket_factory2_(&nat_factory2_),
346 stun_server_(main_, kStunAddr),
347 turn_server_(main_, kTurnUdpIntAddr, kTurnUdpExtAddr),
348 relay_server_(main_, kRelayUdpIntAddr, kRelayUdpExtAddr,
349 kRelayTcpIntAddr, kRelayTcpExtAddr,
350 kRelaySslTcpIntAddr, kRelaySslTcpExtAddr),
351 username_(talk_base::CreateRandomString(ICE_UFRAG_LENGTH)),
352 password_(talk_base::CreateRandomString(ICE_PWD_LENGTH)),
353 ice_protocol_(cricket::ICEPROTO_GOOGLE),
wu@webrtc.orgf6d6ed02014-01-03 22:08:47 +0000354 role_conflict_(false),
355 destroyed_(false) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000356 network_.AddIP(talk_base::IPAddress(INADDR_ANY));
357 }
358
359 protected:
360 static void SetUpTestCase() {
mallinath@webrtc.org5a59ccb2014-02-07 23:22:00 +0000361 talk_base::InitializeSSL();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000362 }
363
mallinath@webrtc.org5a59ccb2014-02-07 23:22:00 +0000364 static void TearDownTestCase() {
365 talk_base::CleanupSSL();
366 }
367
368
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000369 void TestLocalToLocal() {
370 Port* port1 = CreateUdpPort(kLocalAddr1);
371 Port* port2 = CreateUdpPort(kLocalAddr2);
372 TestConnectivity("udp", port1, "udp", port2, true, true, true, true);
373 }
374 void TestLocalToStun(NATType ntype) {
375 Port* port1 = CreateUdpPort(kLocalAddr1);
376 nat_server2_.reset(CreateNatServer(kNatAddr2, ntype));
377 Port* port2 = CreateStunPort(kLocalAddr2, &nat_socket_factory2_);
378 TestConnectivity("udp", port1, StunName(ntype), port2,
379 ntype == NAT_OPEN_CONE, true,
380 ntype != NAT_SYMMETRIC, true);
381 }
382 void TestLocalToRelay(RelayType rtype, ProtocolType proto) {
383 Port* port1 = CreateUdpPort(kLocalAddr1);
384 Port* port2 = CreateRelayPort(kLocalAddr2, rtype, proto, PROTO_UDP);
385 TestConnectivity("udp", port1, RelayName(rtype, proto), port2,
386 rtype == RELAY_GTURN, true, true, true);
387 }
388 void TestStunToLocal(NATType ntype) {
389 nat_server1_.reset(CreateNatServer(kNatAddr1, ntype));
390 Port* port1 = CreateStunPort(kLocalAddr1, &nat_socket_factory1_);
391 Port* port2 = CreateUdpPort(kLocalAddr2);
392 TestConnectivity(StunName(ntype), port1, "udp", port2,
393 true, ntype != NAT_SYMMETRIC, true, true);
394 }
395 void TestStunToStun(NATType ntype1, NATType ntype2) {
396 nat_server1_.reset(CreateNatServer(kNatAddr1, ntype1));
397 Port* port1 = CreateStunPort(kLocalAddr1, &nat_socket_factory1_);
398 nat_server2_.reset(CreateNatServer(kNatAddr2, ntype2));
399 Port* port2 = CreateStunPort(kLocalAddr2, &nat_socket_factory2_);
400 TestConnectivity(StunName(ntype1), port1, StunName(ntype2), port2,
401 ntype2 == NAT_OPEN_CONE,
402 ntype1 != NAT_SYMMETRIC, ntype2 != NAT_SYMMETRIC,
403 ntype1 + ntype2 < (NAT_PORT_RESTRICTED + NAT_SYMMETRIC));
404 }
405 void TestStunToRelay(NATType ntype, RelayType rtype, ProtocolType proto) {
406 nat_server1_.reset(CreateNatServer(kNatAddr1, ntype));
407 Port* port1 = CreateStunPort(kLocalAddr1, &nat_socket_factory1_);
408 Port* port2 = CreateRelayPort(kLocalAddr2, rtype, proto, PROTO_UDP);
409 TestConnectivity(StunName(ntype), port1, RelayName(rtype, proto), port2,
410 rtype == RELAY_GTURN, ntype != NAT_SYMMETRIC, true, true);
411 }
412 void TestTcpToTcp() {
413 Port* port1 = CreateTcpPort(kLocalAddr1);
414 Port* port2 = CreateTcpPort(kLocalAddr2);
415 TestConnectivity("tcp", port1, "tcp", port2, true, false, true, true);
416 }
417 void TestTcpToRelay(RelayType rtype, ProtocolType proto) {
418 Port* port1 = CreateTcpPort(kLocalAddr1);
419 Port* port2 = CreateRelayPort(kLocalAddr2, rtype, proto, PROTO_TCP);
420 TestConnectivity("tcp", port1, RelayName(rtype, proto), port2,
421 rtype == RELAY_GTURN, false, true, true);
422 }
423 void TestSslTcpToRelay(RelayType rtype, ProtocolType proto) {
424 Port* port1 = CreateTcpPort(kLocalAddr1);
425 Port* port2 = CreateRelayPort(kLocalAddr2, rtype, proto, PROTO_SSLTCP);
426 TestConnectivity("ssltcp", port1, RelayName(rtype, proto), port2,
427 rtype == RELAY_GTURN, false, true, true);
428 }
429
430 // helpers for above functions
431 UDPPort* CreateUdpPort(const SocketAddress& addr) {
432 return CreateUdpPort(addr, &socket_factory_);
433 }
434 UDPPort* CreateUdpPort(const SocketAddress& addr,
435 PacketSocketFactory* socket_factory) {
436 UDPPort* port = UDPPort::Create(main_, socket_factory, &network_,
437 addr.ipaddr(), 0, 0, username_, password_);
438 port->SetIceProtocolType(ice_protocol_);
439 return port;
440 }
441 TCPPort* CreateTcpPort(const SocketAddress& addr) {
442 TCPPort* port = CreateTcpPort(addr, &socket_factory_);
443 port->SetIceProtocolType(ice_protocol_);
444 return port;
445 }
446 TCPPort* CreateTcpPort(const SocketAddress& addr,
447 PacketSocketFactory* socket_factory) {
448 TCPPort* port = TCPPort::Create(main_, socket_factory, &network_,
449 addr.ipaddr(), 0, 0, username_, password_,
450 true);
451 port->SetIceProtocolType(ice_protocol_);
452 return port;
453 }
454 StunPort* CreateStunPort(const SocketAddress& addr,
455 talk_base::PacketSocketFactory* factory) {
456 StunPort* port = StunPort::Create(main_, factory, &network_,
457 addr.ipaddr(), 0, 0,
458 username_, password_, kStunAddr);
459 port->SetIceProtocolType(ice_protocol_);
460 return port;
461 }
462 Port* CreateRelayPort(const SocketAddress& addr, RelayType rtype,
463 ProtocolType int_proto, ProtocolType ext_proto) {
464 if (rtype == RELAY_TURN) {
465 return CreateTurnPort(addr, &socket_factory_, int_proto, ext_proto);
466 } else {
467 return CreateGturnPort(addr, int_proto, ext_proto);
468 }
469 }
470 TurnPort* CreateTurnPort(const SocketAddress& addr,
471 PacketSocketFactory* socket_factory,
472 ProtocolType int_proto, ProtocolType ext_proto) {
buildbot@webrtc.orgff90ed62014-04-25 21:12:10 +0000473 return CreateTurnPort(addr, socket_factory,
474 int_proto, ext_proto, kTurnUdpIntAddr);
475 }
476 TurnPort* CreateTurnPort(const SocketAddress& addr,
477 PacketSocketFactory* socket_factory,
478 ProtocolType int_proto, ProtocolType ext_proto,
479 const talk_base::SocketAddress& server_addr) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000480 TurnPort* port = TurnPort::Create(main_, socket_factory, &network_,
481 addr.ipaddr(), 0, 0,
482 username_, password_, ProtocolAddress(
buildbot@webrtc.orgff90ed62014-04-25 21:12:10 +0000483 server_addr, PROTO_UDP),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000484 kRelayCredentials);
485 port->SetIceProtocolType(ice_protocol_);
486 return port;
487 }
488 RelayPort* CreateGturnPort(const SocketAddress& addr,
489 ProtocolType int_proto, ProtocolType ext_proto) {
490 RelayPort* port = CreateGturnPort(addr);
491 SocketAddress addrs[] =
492 { kRelayUdpIntAddr, kRelayTcpIntAddr, kRelaySslTcpIntAddr };
493 port->AddServerAddress(ProtocolAddress(addrs[int_proto], int_proto));
494 return port;
495 }
496 RelayPort* CreateGturnPort(const SocketAddress& addr) {
497 RelayPort* port = RelayPort::Create(main_, &socket_factory_, &network_,
498 addr.ipaddr(), 0, 0,
499 username_, password_);
500 // TODO: Add an external address for ext_proto, so that the
501 // other side can connect to this port using a non-UDP protocol.
502 port->SetIceProtocolType(ice_protocol_);
503 return port;
504 }
505 talk_base::NATServer* CreateNatServer(const SocketAddress& addr,
506 talk_base::NATType type) {
507 return new talk_base::NATServer(type, ss_.get(), addr, ss_.get(), addr);
508 }
509 static const char* StunName(NATType type) {
510 switch (type) {
511 case NAT_OPEN_CONE: return "stun(open cone)";
512 case NAT_ADDR_RESTRICTED: return "stun(addr restricted)";
513 case NAT_PORT_RESTRICTED: return "stun(port restricted)";
514 case NAT_SYMMETRIC: return "stun(symmetric)";
515 default: return "stun(?)";
516 }
517 }
518 static const char* RelayName(RelayType type, ProtocolType proto) {
519 if (type == RELAY_TURN) {
520 switch (proto) {
521 case PROTO_UDP: return "turn(udp)";
522 case PROTO_TCP: return "turn(tcp)";
523 case PROTO_SSLTCP: return "turn(ssltcp)";
524 default: return "turn(?)";
525 }
526 } else {
527 switch (proto) {
528 case PROTO_UDP: return "gturn(udp)";
529 case PROTO_TCP: return "gturn(tcp)";
530 case PROTO_SSLTCP: return "gturn(ssltcp)";
531 default: return "gturn(?)";
532 }
533 }
534 }
535
536 void TestCrossFamilyPorts(int type);
537
wu@webrtc.orgf6d6ed02014-01-03 22:08:47 +0000538 // This does all the work and then deletes |port1| and |port2|.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000539 void TestConnectivity(const char* name1, Port* port1,
540 const char* name2, Port* port2,
541 bool accept, bool same_addr1,
542 bool same_addr2, bool possible);
543
wu@webrtc.orgf6d6ed02014-01-03 22:08:47 +0000544 // This connects and disconnects the provided channels in the same sequence as
545 // TestConnectivity with all options set to |true|. It does not delete either
546 // channel.
547 void ConnectAndDisconnectChannels(TestChannel* ch1, TestChannel* ch2);
548
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000549 void SetIceProtocolType(cricket::IceProtocolType protocol) {
550 ice_protocol_ = protocol;
551 }
552
553 IceMessage* CreateStunMessage(int type) {
554 IceMessage* msg = new IceMessage();
555 msg->SetType(type);
556 msg->SetTransactionID("TESTTESTTEST");
557 return msg;
558 }
559 IceMessage* CreateStunMessageWithUsername(int type,
560 const std::string& username) {
561 IceMessage* msg = CreateStunMessage(type);
562 msg->AddAttribute(
563 new StunByteStringAttribute(STUN_ATTR_USERNAME, username));
564 return msg;
565 }
566 TestPort* CreateTestPort(const talk_base::SocketAddress& addr,
567 const std::string& username,
568 const std::string& password) {
569 TestPort* port = new TestPort(main_, "test", &socket_factory_, &network_,
570 addr.ipaddr(), 0, 0, username, password);
571 port->SignalRoleConflict.connect(this, &PortTest::OnRoleConflict);
572 return port;
573 }
574 TestPort* CreateTestPort(const talk_base::SocketAddress& addr,
575 const std::string& username,
576 const std::string& password,
577 cricket::IceProtocolType type,
mallinath@webrtc.orga5506692013-08-12 21:18:15 +0000578 cricket::IceRole role,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000579 int tiebreaker) {
580 TestPort* port = CreateTestPort(addr, username, password);
581 port->SetIceProtocolType(type);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +0000582 port->SetIceRole(role);
583 port->SetIceTiebreaker(tiebreaker);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000584 return port;
585 }
586
587 void OnRoleConflict(PortInterface* port) {
588 role_conflict_ = true;
589 }
590 bool role_conflict() const { return role_conflict_; }
591
wu@webrtc.orgf6d6ed02014-01-03 22:08:47 +0000592 void ConnectToSignalDestroyed(PortInterface* port) {
593 port->SignalDestroyed.connect(this, &PortTest::OnDestroyed);
594 }
595
596 void OnDestroyed(PortInterface* port) {
597 destroyed_ = true;
598 }
599 bool destroyed() const { return destroyed_; }
600
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000601 talk_base::BasicPacketSocketFactory* nat_socket_factory1() {
602 return &nat_socket_factory1_;
603 }
604
605 private:
606 talk_base::Thread* main_;
607 talk_base::scoped_ptr<talk_base::PhysicalSocketServer> pss_;
608 talk_base::scoped_ptr<talk_base::VirtualSocketServer> ss_;
609 talk_base::SocketServerScope ss_scope_;
610 talk_base::Network network_;
611 talk_base::BasicPacketSocketFactory socket_factory_;
612 talk_base::scoped_ptr<talk_base::NATServer> nat_server1_;
613 talk_base::scoped_ptr<talk_base::NATServer> nat_server2_;
614 talk_base::NATSocketFactory nat_factory1_;
615 talk_base::NATSocketFactory nat_factory2_;
616 talk_base::BasicPacketSocketFactory nat_socket_factory1_;
617 talk_base::BasicPacketSocketFactory nat_socket_factory2_;
618 TestStunServer stun_server_;
619 TestTurnServer turn_server_;
620 TestRelayServer relay_server_;
621 std::string username_;
622 std::string password_;
623 cricket::IceProtocolType ice_protocol_;
624 bool role_conflict_;
wu@webrtc.orgf6d6ed02014-01-03 22:08:47 +0000625 bool destroyed_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000626};
627
628void PortTest::TestConnectivity(const char* name1, Port* port1,
629 const char* name2, Port* port2,
630 bool accept, bool same_addr1,
631 bool same_addr2, bool possible) {
632 LOG(LS_INFO) << "Test: " << name1 << " to " << name2 << ": ";
633 port1->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
634 port2->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
635
wu@webrtc.orgf6d6ed02014-01-03 22:08:47 +0000636 // Set up channels and ensure both ports will be deleted.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000637 TestChannel ch1(port1, port2);
638 TestChannel ch2(port2, port1);
639 EXPECT_EQ(0, ch1.complete_count());
640 EXPECT_EQ(0, ch2.complete_count());
641
642 // Acquire addresses.
643 ch1.Start();
644 ch2.Start();
645 ASSERT_EQ_WAIT(1, ch1.complete_count(), kTimeout);
646 ASSERT_EQ_WAIT(1, ch2.complete_count(), kTimeout);
647
648 // Send a ping from src to dst. This may or may not make it.
649 ch1.CreateConnection();
650 ASSERT_TRUE(ch1.conn() != NULL);
651 EXPECT_TRUE_WAIT(ch1.conn()->connected(), kTimeout); // for TCP connect
652 ch1.Ping();
653 WAIT(!ch2.remote_address().IsNil(), kTimeout);
654
655 if (accept) {
656 // We are able to send a ping from src to dst. This is the case when
657 // sending to UDP ports and cone NATs.
658 EXPECT_TRUE(ch1.remote_address().IsNil());
659 EXPECT_EQ(ch2.remote_fragment(), port1->username_fragment());
660
661 // Ensure the ping came from the same address used for src.
662 // This is the case unless the source NAT was symmetric.
663 if (same_addr1) EXPECT_EQ(ch2.remote_address(), GetAddress(port1));
664 EXPECT_TRUE(same_addr2);
665
666 // Send a ping from dst to src.
667 ch2.AcceptConnection();
668 ASSERT_TRUE(ch2.conn() != NULL);
669 ch2.Ping();
670 EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch2.conn()->write_state(),
671 kTimeout);
672 } else {
673 // We can't send a ping from src to dst, so flip it around. This will happen
674 // when the destination NAT is addr/port restricted or symmetric.
675 EXPECT_TRUE(ch1.remote_address().IsNil());
676 EXPECT_TRUE(ch2.remote_address().IsNil());
677
678 // Send a ping from dst to src. Again, this may or may not make it.
679 ch2.CreateConnection();
680 ASSERT_TRUE(ch2.conn() != NULL);
681 ch2.Ping();
682 WAIT(ch2.conn()->write_state() == Connection::STATE_WRITABLE, kTimeout);
683
684 if (same_addr1 && same_addr2) {
685 // The new ping got back to the source.
686 EXPECT_EQ(Connection::STATE_READABLE, ch1.conn()->read_state());
687 EXPECT_EQ(Connection::STATE_WRITABLE, ch2.conn()->write_state());
688
689 // First connection may not be writable if the first ping did not get
690 // through. So we will have to do another.
691 if (ch1.conn()->write_state() == Connection::STATE_WRITE_INIT) {
692 ch1.Ping();
693 EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch1.conn()->write_state(),
694 kTimeout);
695 }
696 } else if (!same_addr1 && possible) {
697 // The new ping went to the candidate address, but that address was bad.
698 // This will happen when the source NAT is symmetric.
699 EXPECT_TRUE(ch1.remote_address().IsNil());
700 EXPECT_TRUE(ch2.remote_address().IsNil());
701
702 // However, since we have now sent a ping to the source IP, we should be
703 // able to get a ping from it. This gives us the real source address.
704 ch1.Ping();
705 EXPECT_TRUE_WAIT(!ch2.remote_address().IsNil(), kTimeout);
706 EXPECT_EQ(Connection::STATE_READ_INIT, ch2.conn()->read_state());
707 EXPECT_TRUE(ch1.remote_address().IsNil());
708
709 // Pick up the actual address and establish the connection.
710 ch2.AcceptConnection();
711 ASSERT_TRUE(ch2.conn() != NULL);
712 ch2.Ping();
713 EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch2.conn()->write_state(),
714 kTimeout);
715 } else if (!same_addr2 && possible) {
716 // The new ping came in, but from an unexpected address. This will happen
717 // when the destination NAT is symmetric.
718 EXPECT_FALSE(ch1.remote_address().IsNil());
719 EXPECT_EQ(Connection::STATE_READ_INIT, ch1.conn()->read_state());
720
721 // Update our address and complete the connection.
722 ch1.AcceptConnection();
723 ch1.Ping();
724 EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch1.conn()->write_state(),
725 kTimeout);
726 } else { // (!possible)
727 // There should be s no way for the pings to reach each other. Check it.
728 EXPECT_TRUE(ch1.remote_address().IsNil());
729 EXPECT_TRUE(ch2.remote_address().IsNil());
730 ch1.Ping();
731 WAIT(!ch2.remote_address().IsNil(), kTimeout);
732 EXPECT_TRUE(ch1.remote_address().IsNil());
733 EXPECT_TRUE(ch2.remote_address().IsNil());
734 }
735 }
736
737 // Everything should be good, unless we know the situation is impossible.
738 ASSERT_TRUE(ch1.conn() != NULL);
739 ASSERT_TRUE(ch2.conn() != NULL);
740 if (possible) {
741 EXPECT_EQ(Connection::STATE_READABLE, ch1.conn()->read_state());
742 EXPECT_EQ(Connection::STATE_WRITABLE, ch1.conn()->write_state());
743 EXPECT_EQ(Connection::STATE_READABLE, ch2.conn()->read_state());
744 EXPECT_EQ(Connection::STATE_WRITABLE, ch2.conn()->write_state());
745 } else {
746 EXPECT_NE(Connection::STATE_READABLE, ch1.conn()->read_state());
747 EXPECT_NE(Connection::STATE_WRITABLE, ch1.conn()->write_state());
748 EXPECT_NE(Connection::STATE_READABLE, ch2.conn()->read_state());
749 EXPECT_NE(Connection::STATE_WRITABLE, ch2.conn()->write_state());
750 }
751
752 // Tear down and ensure that goes smoothly.
753 ch1.Stop();
754 ch2.Stop();
755 EXPECT_TRUE_WAIT(ch1.conn() == NULL, kTimeout);
756 EXPECT_TRUE_WAIT(ch2.conn() == NULL, kTimeout);
757}
758
wu@webrtc.orgf6d6ed02014-01-03 22:08:47 +0000759void PortTest::ConnectAndDisconnectChannels(TestChannel* ch1,
760 TestChannel* ch2) {
761 // Acquire addresses.
762 ch1->Start();
763 ch2->Start();
764
765 // Send a ping from src to dst.
766 ch1->CreateConnection();
767 EXPECT_TRUE_WAIT(ch1->conn()->connected(), kTimeout); // for TCP connect
768 ch1->Ping();
769 WAIT(!ch2->remote_address().IsNil(), kTimeout);
770
771 // Send a ping from dst to src.
772 ch2->AcceptConnection();
773 ch2->Ping();
774 EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch2->conn()->write_state(),
775 kTimeout);
776
777 // Destroy the connections.
778 ch1->Stop();
779 ch2->Stop();
780}
781
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000782class FakePacketSocketFactory : public talk_base::PacketSocketFactory {
783 public:
784 FakePacketSocketFactory()
785 : next_udp_socket_(NULL),
786 next_server_tcp_socket_(NULL),
787 next_client_tcp_socket_(NULL) {
788 }
789 virtual ~FakePacketSocketFactory() { }
790
791 virtual AsyncPacketSocket* CreateUdpSocket(
792 const SocketAddress& address, int min_port, int max_port) {
793 EXPECT_TRUE(next_udp_socket_ != NULL);
794 AsyncPacketSocket* result = next_udp_socket_;
795 next_udp_socket_ = NULL;
796 return result;
797 }
798
799 virtual AsyncPacketSocket* CreateServerTcpSocket(
800 const SocketAddress& local_address, int min_port, int max_port,
801 int opts) {
802 EXPECT_TRUE(next_server_tcp_socket_ != NULL);
803 AsyncPacketSocket* result = next_server_tcp_socket_;
804 next_server_tcp_socket_ = NULL;
805 return result;
806 }
807
808 // TODO: |proxy_info| and |user_agent| should be set
809 // per-factory and not when socket is created.
810 virtual AsyncPacketSocket* CreateClientTcpSocket(
811 const SocketAddress& local_address, const SocketAddress& remote_address,
812 const talk_base::ProxyInfo& proxy_info,
813 const std::string& user_agent, int opts) {
814 EXPECT_TRUE(next_client_tcp_socket_ != NULL);
815 AsyncPacketSocket* result = next_client_tcp_socket_;
816 next_client_tcp_socket_ = NULL;
817 return result;
818 }
819
820 void set_next_udp_socket(AsyncPacketSocket* next_udp_socket) {
821 next_udp_socket_ = next_udp_socket;
822 }
823 void set_next_server_tcp_socket(AsyncPacketSocket* next_server_tcp_socket) {
824 next_server_tcp_socket_ = next_server_tcp_socket;
825 }
826 void set_next_client_tcp_socket(AsyncPacketSocket* next_client_tcp_socket) {
827 next_client_tcp_socket_ = next_client_tcp_socket;
828 }
sergeyu@chromium.orga23f0ca2013-11-13 22:48:52 +0000829 talk_base::AsyncResolverInterface* CreateAsyncResolver() {
830 return NULL;
831 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000832
833 private:
834 AsyncPacketSocket* next_udp_socket_;
835 AsyncPacketSocket* next_server_tcp_socket_;
836 AsyncPacketSocket* next_client_tcp_socket_;
837};
838
839class FakeAsyncPacketSocket : public AsyncPacketSocket {
840 public:
841 // Returns current local address. Address may be set to NULL if the
842 // socket is not bound yet (GetState() returns STATE_BINDING).
843 virtual SocketAddress GetLocalAddress() const {
844 return SocketAddress();
845 }
846
847 // Returns remote address. Returns zeroes if this is not a client TCP socket.
848 virtual SocketAddress GetRemoteAddress() const {
849 return SocketAddress();
850 }
851
852 // Send a packet.
mallinath@webrtc.org1112c302013-09-23 20:34:45 +0000853 virtual int Send(const void *pv, size_t cb,
mallinath@webrtc.org385857d2014-02-14 00:56:12 +0000854 const talk_base::PacketOptions& options) {
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000855 return static_cast<int>(cb);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000856 }
mallinath@webrtc.org1112c302013-09-23 20:34:45 +0000857 virtual int SendTo(const void *pv, size_t cb, const SocketAddress& addr,
mallinath@webrtc.org385857d2014-02-14 00:56:12 +0000858 const talk_base::PacketOptions& options) {
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000859 return static_cast<int>(cb);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000860 }
861 virtual int Close() {
862 return 0;
863 }
864
865 virtual State GetState() const { return state_; }
866 virtual int GetOption(Socket::Option opt, int* value) { return 0; }
867 virtual int SetOption(Socket::Option opt, int value) { return 0; }
868 virtual int GetError() const { return 0; }
869 virtual void SetError(int error) { }
870
871 void set_state(State state) { state_ = state; }
872
873 private:
874 State state_;
875};
876
877// Local -> XXXX
878TEST_F(PortTest, TestLocalToLocal) {
879 TestLocalToLocal();
880}
881
882TEST_F(PortTest, TestLocalToConeNat) {
883 TestLocalToStun(NAT_OPEN_CONE);
884}
885
886TEST_F(PortTest, TestLocalToARNat) {
887 TestLocalToStun(NAT_ADDR_RESTRICTED);
888}
889
890TEST_F(PortTest, TestLocalToPRNat) {
891 TestLocalToStun(NAT_PORT_RESTRICTED);
892}
893
894TEST_F(PortTest, TestLocalToSymNat) {
895 TestLocalToStun(NAT_SYMMETRIC);
896}
897
phoglund@webrtc.orgf666ecc2014-05-27 08:08:00 +0000898// Flaky: https://code.google.com/p/webrtc/issues/detail?id=3316.
899TEST_F(PortTest, DISABLED_TestLocalToTurn) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000900 TestLocalToRelay(RELAY_TURN, PROTO_UDP);
901}
902
903TEST_F(PortTest, TestLocalToGturn) {
904 TestLocalToRelay(RELAY_GTURN, PROTO_UDP);
905}
906
907TEST_F(PortTest, TestLocalToTcpGturn) {
908 TestLocalToRelay(RELAY_GTURN, PROTO_TCP);
909}
910
911TEST_F(PortTest, TestLocalToSslTcpGturn) {
912 TestLocalToRelay(RELAY_GTURN, PROTO_SSLTCP);
913}
914
915// Cone NAT -> XXXX
916TEST_F(PortTest, TestConeNatToLocal) {
917 TestStunToLocal(NAT_OPEN_CONE);
918}
919
920TEST_F(PortTest, TestConeNatToConeNat) {
921 TestStunToStun(NAT_OPEN_CONE, NAT_OPEN_CONE);
922}
923
924TEST_F(PortTest, TestConeNatToARNat) {
925 TestStunToStun(NAT_OPEN_CONE, NAT_ADDR_RESTRICTED);
926}
927
928TEST_F(PortTest, TestConeNatToPRNat) {
929 TestStunToStun(NAT_OPEN_CONE, NAT_PORT_RESTRICTED);
930}
931
932TEST_F(PortTest, TestConeNatToSymNat) {
933 TestStunToStun(NAT_OPEN_CONE, NAT_SYMMETRIC);
934}
935
936TEST_F(PortTest, TestConeNatToTurn) {
937 TestStunToRelay(NAT_OPEN_CONE, RELAY_TURN, PROTO_UDP);
938}
939
940TEST_F(PortTest, TestConeNatToGturn) {
941 TestStunToRelay(NAT_OPEN_CONE, RELAY_GTURN, PROTO_UDP);
942}
943
944TEST_F(PortTest, TestConeNatToTcpGturn) {
945 TestStunToRelay(NAT_OPEN_CONE, RELAY_GTURN, PROTO_TCP);
946}
947
948// Address-restricted NAT -> XXXX
949TEST_F(PortTest, TestARNatToLocal) {
950 TestStunToLocal(NAT_ADDR_RESTRICTED);
951}
952
953TEST_F(PortTest, TestARNatToConeNat) {
954 TestStunToStun(NAT_ADDR_RESTRICTED, NAT_OPEN_CONE);
955}
956
957TEST_F(PortTest, TestARNatToARNat) {
958 TestStunToStun(NAT_ADDR_RESTRICTED, NAT_ADDR_RESTRICTED);
959}
960
961TEST_F(PortTest, TestARNatToPRNat) {
962 TestStunToStun(NAT_ADDR_RESTRICTED, NAT_PORT_RESTRICTED);
963}
964
965TEST_F(PortTest, TestARNatToSymNat) {
966 TestStunToStun(NAT_ADDR_RESTRICTED, NAT_SYMMETRIC);
967}
968
969TEST_F(PortTest, TestARNatToTurn) {
970 TestStunToRelay(NAT_ADDR_RESTRICTED, RELAY_TURN, PROTO_UDP);
971}
972
973TEST_F(PortTest, TestARNatToGturn) {
974 TestStunToRelay(NAT_ADDR_RESTRICTED, RELAY_GTURN, PROTO_UDP);
975}
976
977TEST_F(PortTest, TestARNATNatToTcpGturn) {
978 TestStunToRelay(NAT_ADDR_RESTRICTED, RELAY_GTURN, PROTO_TCP);
979}
980
981// Port-restricted NAT -> XXXX
982TEST_F(PortTest, TestPRNatToLocal) {
983 TestStunToLocal(NAT_PORT_RESTRICTED);
984}
985
986TEST_F(PortTest, TestPRNatToConeNat) {
987 TestStunToStun(NAT_PORT_RESTRICTED, NAT_OPEN_CONE);
988}
989
990TEST_F(PortTest, TestPRNatToARNat) {
991 TestStunToStun(NAT_PORT_RESTRICTED, NAT_ADDR_RESTRICTED);
992}
993
994TEST_F(PortTest, TestPRNatToPRNat) {
995 TestStunToStun(NAT_PORT_RESTRICTED, NAT_PORT_RESTRICTED);
996}
997
998TEST_F(PortTest, TestPRNatToSymNat) {
999 // Will "fail"
1000 TestStunToStun(NAT_PORT_RESTRICTED, NAT_SYMMETRIC);
1001}
1002
1003TEST_F(PortTest, TestPRNatToTurn) {
1004 TestStunToRelay(NAT_PORT_RESTRICTED, RELAY_TURN, PROTO_UDP);
1005}
1006
1007TEST_F(PortTest, TestPRNatToGturn) {
1008 TestStunToRelay(NAT_PORT_RESTRICTED, RELAY_GTURN, PROTO_UDP);
1009}
1010
1011TEST_F(PortTest, TestPRNatToTcpGturn) {
1012 TestStunToRelay(NAT_PORT_RESTRICTED, RELAY_GTURN, PROTO_TCP);
1013}
1014
1015// Symmetric NAT -> XXXX
1016TEST_F(PortTest, TestSymNatToLocal) {
1017 TestStunToLocal(NAT_SYMMETRIC);
1018}
1019
1020TEST_F(PortTest, TestSymNatToConeNat) {
1021 TestStunToStun(NAT_SYMMETRIC, NAT_OPEN_CONE);
1022}
1023
1024TEST_F(PortTest, TestSymNatToARNat) {
1025 TestStunToStun(NAT_SYMMETRIC, NAT_ADDR_RESTRICTED);
1026}
1027
1028TEST_F(PortTest, TestSymNatToPRNat) {
1029 // Will "fail"
1030 TestStunToStun(NAT_SYMMETRIC, NAT_PORT_RESTRICTED);
1031}
1032
1033TEST_F(PortTest, TestSymNatToSymNat) {
1034 // Will "fail"
1035 TestStunToStun(NAT_SYMMETRIC, NAT_SYMMETRIC);
1036}
1037
1038TEST_F(PortTest, TestSymNatToTurn) {
1039 TestStunToRelay(NAT_SYMMETRIC, RELAY_TURN, PROTO_UDP);
1040}
1041
1042TEST_F(PortTest, TestSymNatToGturn) {
1043 TestStunToRelay(NAT_SYMMETRIC, RELAY_GTURN, PROTO_UDP);
1044}
1045
1046TEST_F(PortTest, TestSymNatToTcpGturn) {
1047 TestStunToRelay(NAT_SYMMETRIC, RELAY_GTURN, PROTO_TCP);
1048}
1049
1050// Outbound TCP -> XXXX
1051TEST_F(PortTest, TestTcpToTcp) {
1052 TestTcpToTcp();
1053}
1054
1055/* TODO: Enable these once testrelayserver can accept external TCP.
1056TEST_F(PortTest, TestTcpToTcpRelay) {
1057 TestTcpToRelay(PROTO_TCP);
1058}
1059
1060TEST_F(PortTest, TestTcpToSslTcpRelay) {
1061 TestTcpToRelay(PROTO_SSLTCP);
1062}
1063*/
1064
1065// Outbound SSLTCP -> XXXX
1066/* TODO: Enable these once testrelayserver can accept external SSL.
1067TEST_F(PortTest, TestSslTcpToTcpRelay) {
1068 TestSslTcpToRelay(PROTO_TCP);
1069}
1070
1071TEST_F(PortTest, TestSslTcpToSslTcpRelay) {
1072 TestSslTcpToRelay(PROTO_SSLTCP);
1073}
1074*/
1075
1076// This test case verifies standard ICE features in STUN messages. Currently it
1077// verifies Message Integrity attribute in STUN messages and username in STUN
1078// binding request will have colon (":") between remote and local username.
1079TEST_F(PortTest, TestLocalToLocalAsIce) {
1080 SetIceProtocolType(cricket::ICEPROTO_RFC5245);
1081 UDPPort* port1 = CreateUdpPort(kLocalAddr1);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00001082 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
1083 port1->SetIceTiebreaker(kTiebreaker1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001084 ASSERT_EQ(cricket::ICEPROTO_RFC5245, port1->IceProtocol());
1085 UDPPort* port2 = CreateUdpPort(kLocalAddr2);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00001086 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
1087 port2->SetIceTiebreaker(kTiebreaker2);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001088 ASSERT_EQ(cricket::ICEPROTO_RFC5245, port2->IceProtocol());
1089 // Same parameters as TestLocalToLocal above.
1090 TestConnectivity("udp", port1, "udp", port2, true, true, true, true);
1091}
1092
1093// This test is trying to validate a successful and failure scenario in a
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00001094// loopback test when protocol is RFC5245. For success IceTiebreaker, username
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001095// should remain equal to the request generated by the port and role of port
1096// must be in controlling.
1097TEST_F(PortTest, TestLoopbackCallAsIce) {
1098 talk_base::scoped_ptr<TestPort> lport(
1099 CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
1100 lport->SetIceProtocolType(ICEPROTO_RFC5245);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00001101 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1102 lport->SetIceTiebreaker(kTiebreaker1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001103 lport->PrepareAddress();
1104 ASSERT_FALSE(lport->Candidates().empty());
1105 Connection* conn = lport->CreateConnection(lport->Candidates()[0],
1106 Port::ORIGIN_MESSAGE);
1107 conn->Ping(0);
1108
1109 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, 1000);
1110 IceMessage* msg = lport->last_stun_msg();
1111 EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
1112 conn->OnReadPacket(lport->last_stun_buf()->Data(),
wu@webrtc.orga9890802013-12-13 00:21:03 +00001113 lport->last_stun_buf()->Length(),
1114 talk_base::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001115 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, 1000);
1116 msg = lport->last_stun_msg();
1117 EXPECT_EQ(STUN_BINDING_RESPONSE, msg->type());
1118
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00001119 // If the tiebreaker value is different from port, we expect a error
1120 // response.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001121 lport->Reset();
1122 lport->AddCandidateAddress(kLocalAddr2);
1123 // Creating a different connection as |conn| is in STATE_READABLE.
1124 Connection* conn1 = lport->CreateConnection(lport->Candidates()[1],
1125 Port::ORIGIN_MESSAGE);
1126 conn1->Ping(0);
1127
1128 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, 1000);
1129 msg = lport->last_stun_msg();
1130 EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001131 talk_base::scoped_ptr<IceMessage> modified_req(
1132 CreateStunMessage(STUN_BINDING_REQUEST));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001133 const StunByteStringAttribute* username_attr = msg->GetByteString(
1134 STUN_ATTR_USERNAME);
1135 modified_req->AddAttribute(new StunByteStringAttribute(
1136 STUN_ATTR_USERNAME, username_attr->GetString()));
1137 // To make sure we receive error response, adding tiebreaker less than
1138 // what's present in request.
1139 modified_req->AddAttribute(new StunUInt64Attribute(
1140 STUN_ATTR_ICE_CONTROLLING, kTiebreaker1 - 1));
1141 modified_req->AddMessageIntegrity("lpass");
1142 modified_req->AddFingerprint();
1143
1144 lport->Reset();
1145 talk_base::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001146 WriteStunMessage(modified_req.get(), buf.get());
wu@webrtc.orga9890802013-12-13 00:21:03 +00001147 conn1->OnReadPacket(buf->Data(), buf->Length(), talk_base::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001148 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, 1000);
1149 msg = lport->last_stun_msg();
1150 EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, msg->type());
1151}
1152
1153// This test verifies role conflict signal is received when there is
1154// conflict in the role. In this case both ports are in controlling and
1155// |rport| has higher tiebreaker value than |lport|. Since |lport| has lower
1156// value of tiebreaker, when it receives ping request from |rport| it will
1157// send role conflict signal.
1158TEST_F(PortTest, TestIceRoleConflict) {
1159 talk_base::scoped_ptr<TestPort> lport(
1160 CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
1161 lport->SetIceProtocolType(ICEPROTO_RFC5245);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00001162 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1163 lport->SetIceTiebreaker(kTiebreaker1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001164 talk_base::scoped_ptr<TestPort> rport(
1165 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1166 rport->SetIceProtocolType(ICEPROTO_RFC5245);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00001167 rport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1168 rport->SetIceTiebreaker(kTiebreaker2);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001169
1170 lport->PrepareAddress();
1171 rport->PrepareAddress();
1172 ASSERT_FALSE(lport->Candidates().empty());
1173 ASSERT_FALSE(rport->Candidates().empty());
1174 Connection* lconn = lport->CreateConnection(rport->Candidates()[0],
1175 Port::ORIGIN_MESSAGE);
1176 Connection* rconn = rport->CreateConnection(lport->Candidates()[0],
1177 Port::ORIGIN_MESSAGE);
1178 rconn->Ping(0);
1179
1180 ASSERT_TRUE_WAIT(rport->last_stun_msg() != NULL, 1000);
1181 IceMessage* msg = rport->last_stun_msg();
1182 EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
1183 // Send rport binding request to lport.
1184 lconn->OnReadPacket(rport->last_stun_buf()->Data(),
wu@webrtc.orga9890802013-12-13 00:21:03 +00001185 rport->last_stun_buf()->Length(),
1186 talk_base::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001187
1188 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, 1000);
1189 EXPECT_EQ(STUN_BINDING_RESPONSE, lport->last_stun_msg()->type());
1190 EXPECT_TRUE(role_conflict());
1191}
1192
1193TEST_F(PortTest, TestTcpNoDelay) {
1194 TCPPort* port1 = CreateTcpPort(kLocalAddr1);
1195 int option_value = -1;
1196 int success = port1->GetOption(talk_base::Socket::OPT_NODELAY,
1197 &option_value);
1198 ASSERT_EQ(0, success); // GetOption() should complete successfully w/ 0
1199 ASSERT_EQ(1, option_value);
1200 delete port1;
1201}
1202
1203TEST_F(PortTest, TestDelayedBindingUdp) {
1204 FakeAsyncPacketSocket *socket = new FakeAsyncPacketSocket();
1205 FakePacketSocketFactory socket_factory;
1206
1207 socket_factory.set_next_udp_socket(socket);
1208 scoped_ptr<UDPPort> port(
1209 CreateUdpPort(kLocalAddr1, &socket_factory));
1210
1211 socket->set_state(AsyncPacketSocket::STATE_BINDING);
1212 port->PrepareAddress();
1213
1214 EXPECT_EQ(0U, port->Candidates().size());
1215 socket->SignalAddressReady(socket, kLocalAddr2);
1216
1217 EXPECT_EQ(1U, port->Candidates().size());
1218}
1219
1220TEST_F(PortTest, TestDelayedBindingTcp) {
1221 FakeAsyncPacketSocket *socket = new FakeAsyncPacketSocket();
1222 FakePacketSocketFactory socket_factory;
1223
1224 socket_factory.set_next_server_tcp_socket(socket);
1225 scoped_ptr<TCPPort> port(
1226 CreateTcpPort(kLocalAddr1, &socket_factory));
1227
1228 socket->set_state(AsyncPacketSocket::STATE_BINDING);
1229 port->PrepareAddress();
1230
1231 EXPECT_EQ(0U, port->Candidates().size());
1232 socket->SignalAddressReady(socket, kLocalAddr2);
1233
1234 EXPECT_EQ(1U, port->Candidates().size());
1235}
1236
1237void PortTest::TestCrossFamilyPorts(int type) {
1238 FakePacketSocketFactory factory;
1239 scoped_ptr<Port> ports[4];
1240 SocketAddress addresses[4] = {SocketAddress("192.168.1.3", 0),
1241 SocketAddress("192.168.1.4", 0),
1242 SocketAddress("2001:db8::1", 0),
1243 SocketAddress("2001:db8::2", 0)};
1244 for (int i = 0; i < 4; i++) {
1245 FakeAsyncPacketSocket *socket = new FakeAsyncPacketSocket();
1246 if (type == SOCK_DGRAM) {
1247 factory.set_next_udp_socket(socket);
1248 ports[i].reset(CreateUdpPort(addresses[i], &factory));
1249 } else if (type == SOCK_STREAM) {
1250 factory.set_next_server_tcp_socket(socket);
1251 ports[i].reset(CreateTcpPort(addresses[i], &factory));
1252 }
1253 socket->set_state(AsyncPacketSocket::STATE_BINDING);
1254 socket->SignalAddressReady(socket, addresses[i]);
1255 ports[i]->PrepareAddress();
1256 }
1257
1258 // IPv4 Port, connects to IPv6 candidate and then to IPv4 candidate.
1259 if (type == SOCK_STREAM) {
1260 FakeAsyncPacketSocket* clientsocket = new FakeAsyncPacketSocket();
1261 factory.set_next_client_tcp_socket(clientsocket);
1262 }
1263 Connection* c = ports[0]->CreateConnection(GetCandidate(ports[2].get()),
1264 Port::ORIGIN_MESSAGE);
1265 EXPECT_TRUE(NULL == c);
1266 EXPECT_EQ(0U, ports[0]->connections().size());
1267 c = ports[0]->CreateConnection(GetCandidate(ports[1].get()),
1268 Port::ORIGIN_MESSAGE);
1269 EXPECT_FALSE(NULL == c);
1270 EXPECT_EQ(1U, ports[0]->connections().size());
1271
1272 // IPv6 Port, connects to IPv4 candidate and to IPv6 candidate.
1273 if (type == SOCK_STREAM) {
1274 FakeAsyncPacketSocket* clientsocket = new FakeAsyncPacketSocket();
1275 factory.set_next_client_tcp_socket(clientsocket);
1276 }
1277 c = ports[2]->CreateConnection(GetCandidate(ports[0].get()),
1278 Port::ORIGIN_MESSAGE);
1279 EXPECT_TRUE(NULL == c);
1280 EXPECT_EQ(0U, ports[2]->connections().size());
1281 c = ports[2]->CreateConnection(GetCandidate(ports[3].get()),
1282 Port::ORIGIN_MESSAGE);
1283 EXPECT_FALSE(NULL == c);
1284 EXPECT_EQ(1U, ports[2]->connections().size());
1285}
1286
1287TEST_F(PortTest, TestSkipCrossFamilyTcp) {
1288 TestCrossFamilyPorts(SOCK_STREAM);
1289}
1290
1291TEST_F(PortTest, TestSkipCrossFamilyUdp) {
1292 TestCrossFamilyPorts(SOCK_DGRAM);
1293}
1294
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00001295// This test verifies DSCP value set through SetOption interface can be
1296// get through DefaultDscpValue.
1297TEST_F(PortTest, TestDefaultDscpValue) {
mallinath@webrtc.org67ee6b92014-02-03 16:57:16 +00001298 int dscp;
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00001299 talk_base::scoped_ptr<UDPPort> udpport(CreateUdpPort(kLocalAddr1));
mallinath@webrtc.org67ee6b92014-02-03 16:57:16 +00001300 EXPECT_EQ(0, udpport->SetOption(talk_base::Socket::OPT_DSCP,
1301 talk_base::DSCP_CS6));
1302 EXPECT_EQ(0, udpport->GetOption(talk_base::Socket::OPT_DSCP, &dscp));
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00001303 talk_base::scoped_ptr<TCPPort> tcpport(CreateTcpPort(kLocalAddr1));
mallinath@webrtc.org67ee6b92014-02-03 16:57:16 +00001304 EXPECT_EQ(0, tcpport->SetOption(talk_base::Socket::OPT_DSCP,
1305 talk_base::DSCP_AF31));
1306 EXPECT_EQ(0, tcpport->GetOption(talk_base::Socket::OPT_DSCP, &dscp));
1307 EXPECT_EQ(talk_base::DSCP_AF31, dscp);
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00001308 talk_base::scoped_ptr<StunPort> stunport(
1309 CreateStunPort(kLocalAddr1, nat_socket_factory1()));
mallinath@webrtc.org67ee6b92014-02-03 16:57:16 +00001310 EXPECT_EQ(0, stunport->SetOption(talk_base::Socket::OPT_DSCP,
1311 talk_base::DSCP_AF41));
1312 EXPECT_EQ(0, stunport->GetOption(talk_base::Socket::OPT_DSCP, &dscp));
1313 EXPECT_EQ(talk_base::DSCP_AF41, dscp);
1314 talk_base::scoped_ptr<TurnPort> turnport1(CreateTurnPort(
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00001315 kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
mallinath@webrtc.org67ee6b92014-02-03 16:57:16 +00001316 // Socket is created in PrepareAddress.
1317 turnport1->PrepareAddress();
1318 EXPECT_EQ(0, turnport1->SetOption(talk_base::Socket::OPT_DSCP,
1319 talk_base::DSCP_CS7));
1320 EXPECT_EQ(0, turnport1->GetOption(talk_base::Socket::OPT_DSCP, &dscp));
1321 EXPECT_EQ(talk_base::DSCP_CS7, dscp);
1322 // This will verify correct value returned without the socket.
1323 talk_base::scoped_ptr<TurnPort> turnport2(CreateTurnPort(
1324 kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
1325 EXPECT_EQ(0, turnport2->SetOption(talk_base::Socket::OPT_DSCP,
1326 talk_base::DSCP_CS6));
1327 EXPECT_EQ(0, turnport2->GetOption(talk_base::Socket::OPT_DSCP, &dscp));
1328 EXPECT_EQ(talk_base::DSCP_CS6, dscp);
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00001329}
1330
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001331// Test sending STUN messages in GICE format.
1332TEST_F(PortTest, TestSendStunMessageAsGice) {
1333 talk_base::scoped_ptr<TestPort> lport(
1334 CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
1335 talk_base::scoped_ptr<TestPort> rport(
1336 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1337 lport->SetIceProtocolType(ICEPROTO_GOOGLE);
1338 rport->SetIceProtocolType(ICEPROTO_GOOGLE);
1339
1340 // Send a fake ping from lport to rport.
1341 lport->PrepareAddress();
1342 rport->PrepareAddress();
1343 ASSERT_FALSE(rport->Candidates().empty());
1344 Connection* conn = lport->CreateConnection(rport->Candidates()[0],
1345 Port::ORIGIN_MESSAGE);
1346 rport->CreateConnection(lport->Candidates()[0], Port::ORIGIN_MESSAGE);
1347 conn->Ping(0);
1348
1349 // Check that it's a proper BINDING-REQUEST.
1350 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, 1000);
1351 IceMessage* msg = lport->last_stun_msg();
1352 EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
1353 EXPECT_FALSE(msg->IsLegacy());
1354 const StunByteStringAttribute* username_attr = msg->GetByteString(
1355 STUN_ATTR_USERNAME);
1356 ASSERT_TRUE(username_attr != NULL);
1357 EXPECT_EQ("rfraglfrag", username_attr->GetString());
1358 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) == NULL);
1359 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_PRIORITY) == NULL);
1360 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_FINGERPRINT) == NULL);
1361
1362 // Save a copy of the BINDING-REQUEST for use below.
1363 talk_base::scoped_ptr<IceMessage> request(CopyStunMessage(msg));
1364
1365 // Respond with a BINDING-RESPONSE.
1366 rport->SendBindingResponse(request.get(), lport->Candidates()[0].address());
1367 msg = rport->last_stun_msg();
1368 ASSERT_TRUE(msg != NULL);
1369 EXPECT_EQ(STUN_BINDING_RESPONSE, msg->type());
1370 EXPECT_FALSE(msg->IsLegacy());
1371 username_attr = msg->GetByteString(STUN_ATTR_USERNAME);
1372 ASSERT_TRUE(username_attr != NULL); // GICE has a username in the response.
1373 EXPECT_EQ("rfraglfrag", username_attr->GetString());
1374 const StunAddressAttribute* addr_attr = msg->GetAddress(
1375 STUN_ATTR_MAPPED_ADDRESS);
1376 ASSERT_TRUE(addr_attr != NULL);
1377 EXPECT_EQ(lport->Candidates()[0].address(), addr_attr->GetAddress());
1378 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_XOR_MAPPED_ADDRESS) == NULL);
1379 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) == NULL);
1380 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_PRIORITY) == NULL);
1381 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_FINGERPRINT) == NULL);
1382
1383 // Respond with a BINDING-ERROR-RESPONSE. This wouldn't happen in real life,
1384 // but we can do it here.
1385 rport->SendBindingErrorResponse(request.get(),
1386 rport->Candidates()[0].address(),
1387 STUN_ERROR_SERVER_ERROR,
1388 STUN_ERROR_REASON_SERVER_ERROR);
1389 msg = rport->last_stun_msg();
1390 ASSERT_TRUE(msg != NULL);
1391 EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, msg->type());
1392 EXPECT_FALSE(msg->IsLegacy());
1393 username_attr = msg->GetByteString(STUN_ATTR_USERNAME);
1394 ASSERT_TRUE(username_attr != NULL); // GICE has a username in the response.
1395 EXPECT_EQ("rfraglfrag", username_attr->GetString());
1396 const StunErrorCodeAttribute* error_attr = msg->GetErrorCode();
1397 ASSERT_TRUE(error_attr != NULL);
1398 // The GICE wire format for error codes is incorrect.
1399 EXPECT_EQ(STUN_ERROR_SERVER_ERROR_AS_GICE, error_attr->code());
1400 EXPECT_EQ(STUN_ERROR_SERVER_ERROR / 256, error_attr->eclass());
1401 EXPECT_EQ(STUN_ERROR_SERVER_ERROR % 256, error_attr->number());
1402 EXPECT_EQ(std::string(STUN_ERROR_REASON_SERVER_ERROR), error_attr->reason());
1403 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_PRIORITY) == NULL);
1404 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) == NULL);
1405 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_FINGERPRINT) == NULL);
1406}
1407
1408// Test sending STUN messages in ICE format.
1409TEST_F(PortTest, TestSendStunMessageAsIce) {
1410 talk_base::scoped_ptr<TestPort> lport(
1411 CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
1412 talk_base::scoped_ptr<TestPort> rport(
1413 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1414 lport->SetIceProtocolType(ICEPROTO_RFC5245);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00001415 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1416 lport->SetIceTiebreaker(kTiebreaker1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001417 rport->SetIceProtocolType(ICEPROTO_RFC5245);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00001418 rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
1419 rport->SetIceTiebreaker(kTiebreaker2);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001420
1421 // Send a fake ping from lport to rport.
1422 lport->PrepareAddress();
1423 rport->PrepareAddress();
1424 ASSERT_FALSE(rport->Candidates().empty());
1425 Connection* lconn = lport->CreateConnection(
1426 rport->Candidates()[0], Port::ORIGIN_MESSAGE);
1427 Connection* rconn = rport->CreateConnection(
1428 lport->Candidates()[0], Port::ORIGIN_MESSAGE);
1429 lconn->Ping(0);
1430
1431 // Check that it's a proper BINDING-REQUEST.
1432 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, 1000);
1433 IceMessage* msg = lport->last_stun_msg();
1434 EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
1435 EXPECT_FALSE(msg->IsLegacy());
1436 const StunByteStringAttribute* username_attr =
1437 msg->GetByteString(STUN_ATTR_USERNAME);
1438 ASSERT_TRUE(username_attr != NULL);
1439 const StunUInt32Attribute* priority_attr = msg->GetUInt32(STUN_ATTR_PRIORITY);
1440 ASSERT_TRUE(priority_attr != NULL);
1441 EXPECT_EQ(kDefaultPrflxPriority, priority_attr->value());
1442 EXPECT_EQ("rfrag:lfrag", username_attr->GetString());
1443 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL);
1444 EXPECT_TRUE(StunMessage::ValidateMessageIntegrity(
1445 lport->last_stun_buf()->Data(), lport->last_stun_buf()->Length(),
1446 "rpass"));
1447 const StunUInt64Attribute* ice_controlling_attr =
1448 msg->GetUInt64(STUN_ATTR_ICE_CONTROLLING);
1449 ASSERT_TRUE(ice_controlling_attr != NULL);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00001450 EXPECT_EQ(lport->IceTiebreaker(), ice_controlling_attr->value());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001451 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_ICE_CONTROLLED) == NULL);
1452 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) != NULL);
1453 EXPECT_TRUE(msg->GetUInt32(STUN_ATTR_FINGERPRINT) != NULL);
1454 EXPECT_TRUE(StunMessage::ValidateFingerprint(
1455 lport->last_stun_buf()->Data(), lport->last_stun_buf()->Length()));
1456
1457 // Request should not include ping count.
1458 ASSERT_TRUE(msg->GetUInt32(STUN_ATTR_RETRANSMIT_COUNT) == NULL);
1459
1460 // Save a copy of the BINDING-REQUEST for use below.
1461 talk_base::scoped_ptr<IceMessage> request(CopyStunMessage(msg));
1462
1463 // Respond with a BINDING-RESPONSE.
1464 rport->SendBindingResponse(request.get(), lport->Candidates()[0].address());
1465 msg = rport->last_stun_msg();
1466 ASSERT_TRUE(msg != NULL);
1467 EXPECT_EQ(STUN_BINDING_RESPONSE, msg->type());
1468
1469
1470 EXPECT_FALSE(msg->IsLegacy());
1471 const StunAddressAttribute* addr_attr = msg->GetAddress(
1472 STUN_ATTR_XOR_MAPPED_ADDRESS);
1473 ASSERT_TRUE(addr_attr != NULL);
1474 EXPECT_EQ(lport->Candidates()[0].address(), addr_attr->GetAddress());
1475 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL);
1476 EXPECT_TRUE(StunMessage::ValidateMessageIntegrity(
1477 rport->last_stun_buf()->Data(), rport->last_stun_buf()->Length(),
1478 "rpass"));
1479 EXPECT_TRUE(msg->GetUInt32(STUN_ATTR_FINGERPRINT) != NULL);
1480 EXPECT_TRUE(StunMessage::ValidateFingerprint(
1481 lport->last_stun_buf()->Data(), lport->last_stun_buf()->Length()));
1482 // No USERNAME or PRIORITY in ICE responses.
1483 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USERNAME) == NULL);
1484 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_PRIORITY) == NULL);
1485 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MAPPED_ADDRESS) == NULL);
1486 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_ICE_CONTROLLING) == NULL);
1487 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_ICE_CONTROLLED) == NULL);
1488 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) == NULL);
1489
1490 // Response should not include ping count.
1491 ASSERT_TRUE(msg->GetUInt32(STUN_ATTR_RETRANSMIT_COUNT) == NULL);
1492
1493 // Respond with a BINDING-ERROR-RESPONSE. This wouldn't happen in real life,
1494 // but we can do it here.
1495 rport->SendBindingErrorResponse(request.get(),
1496 lport->Candidates()[0].address(),
1497 STUN_ERROR_SERVER_ERROR,
1498 STUN_ERROR_REASON_SERVER_ERROR);
1499 msg = rport->last_stun_msg();
1500 ASSERT_TRUE(msg != NULL);
1501 EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, msg->type());
1502 EXPECT_FALSE(msg->IsLegacy());
1503 const StunErrorCodeAttribute* error_attr = msg->GetErrorCode();
1504 ASSERT_TRUE(error_attr != NULL);
1505 EXPECT_EQ(STUN_ERROR_SERVER_ERROR, error_attr->code());
1506 EXPECT_EQ(std::string(STUN_ERROR_REASON_SERVER_ERROR), error_attr->reason());
1507 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL);
1508 EXPECT_TRUE(StunMessage::ValidateMessageIntegrity(
1509 rport->last_stun_buf()->Data(), rport->last_stun_buf()->Length(),
1510 "rpass"));
1511 EXPECT_TRUE(msg->GetUInt32(STUN_ATTR_FINGERPRINT) != NULL);
1512 EXPECT_TRUE(StunMessage::ValidateFingerprint(
1513 lport->last_stun_buf()->Data(), lport->last_stun_buf()->Length()));
1514 // No USERNAME with ICE.
1515 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USERNAME) == NULL);
1516 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_PRIORITY) == NULL);
1517
1518 // Testing STUN binding requests from rport --> lport, having ICE_CONTROLLED
1519 // and (incremented) RETRANSMIT_COUNT attributes.
1520 rport->Reset();
1521 rport->set_send_retransmit_count_attribute(true);
1522 rconn->Ping(0);
1523 rconn->Ping(0);
1524 rconn->Ping(0);
1525 ASSERT_TRUE_WAIT(rport->last_stun_msg() != NULL, 1000);
1526 msg = rport->last_stun_msg();
1527 EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
1528 const StunUInt64Attribute* ice_controlled_attr =
1529 msg->GetUInt64(STUN_ATTR_ICE_CONTROLLED);
1530 ASSERT_TRUE(ice_controlled_attr != NULL);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00001531 EXPECT_EQ(rport->IceTiebreaker(), ice_controlled_attr->value());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001532 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) == NULL);
1533
1534 // Request should include ping count.
1535 const StunUInt32Attribute* retransmit_attr =
1536 msg->GetUInt32(STUN_ATTR_RETRANSMIT_COUNT);
1537 ASSERT_TRUE(retransmit_attr != NULL);
1538 EXPECT_EQ(2U, retransmit_attr->value());
1539
1540 // Respond with a BINDING-RESPONSE.
1541 request.reset(CopyStunMessage(msg));
1542 lport->SendBindingResponse(request.get(), rport->Candidates()[0].address());
1543 msg = lport->last_stun_msg();
1544
1545 // Response should include same ping count.
1546 retransmit_attr = msg->GetUInt32(STUN_ATTR_RETRANSMIT_COUNT);
1547 ASSERT_TRUE(retransmit_attr != NULL);
1548 EXPECT_EQ(2U, retransmit_attr->value());
1549}
1550
1551TEST_F(PortTest, TestUseCandidateAttribute) {
1552 talk_base::scoped_ptr<TestPort> lport(
1553 CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
1554 talk_base::scoped_ptr<TestPort> rport(
1555 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1556 lport->SetIceProtocolType(ICEPROTO_RFC5245);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00001557 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1558 lport->SetIceTiebreaker(kTiebreaker1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001559 rport->SetIceProtocolType(ICEPROTO_RFC5245);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00001560 rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
1561 rport->SetIceTiebreaker(kTiebreaker2);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001562
1563 // Send a fake ping from lport to rport.
1564 lport->PrepareAddress();
1565 rport->PrepareAddress();
1566 ASSERT_FALSE(rport->Candidates().empty());
1567 Connection* lconn = lport->CreateConnection(
1568 rport->Candidates()[0], Port::ORIGIN_MESSAGE);
1569 lconn->Ping(0);
1570 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, 1000);
1571 IceMessage* msg = lport->last_stun_msg();
1572 const StunUInt64Attribute* ice_controlling_attr =
1573 msg->GetUInt64(STUN_ATTR_ICE_CONTROLLING);
1574 ASSERT_TRUE(ice_controlling_attr != NULL);
1575 const StunByteStringAttribute* use_candidate_attr = msg->GetByteString(
1576 STUN_ATTR_USE_CANDIDATE);
1577 ASSERT_TRUE(use_candidate_attr != NULL);
1578}
1579
1580// Test handling STUN messages in GICE format.
1581TEST_F(PortTest, TestHandleStunMessageAsGice) {
1582 // Our port will act as the "remote" port.
1583 talk_base::scoped_ptr<TestPort> port(
1584 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1585 port->SetIceProtocolType(ICEPROTO_GOOGLE);
1586
1587 talk_base::scoped_ptr<IceMessage> in_msg, out_msg;
1588 talk_base::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
1589 talk_base::SocketAddress addr(kLocalAddr1);
1590 std::string username;
1591
1592 // BINDING-REQUEST from local to remote with valid GICE username and no M-I.
1593 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
1594 "rfraglfrag"));
1595 WriteStunMessage(in_msg.get(), buf.get());
1596 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1597 out_msg.accept(), &username));
1598 EXPECT_TRUE(out_msg.get() != NULL); // Succeeds, since this is GICE.
1599 EXPECT_EQ("lfrag", username);
1600
1601 // Add M-I; should be ignored and rest of message parsed normally.
1602 in_msg->AddMessageIntegrity("password");
1603 WriteStunMessage(in_msg.get(), buf.get());
1604 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1605 out_msg.accept(), &username));
1606 EXPECT_TRUE(out_msg.get() != NULL);
1607 EXPECT_EQ("lfrag", username);
1608
1609 // BINDING-RESPONSE with username, as done in GICE. Should succeed.
1610 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_RESPONSE,
1611 "rfraglfrag"));
1612 in_msg->AddAttribute(
1613 new StunAddressAttribute(STUN_ATTR_MAPPED_ADDRESS, kLocalAddr2));
1614 WriteStunMessage(in_msg.get(), buf.get());
1615 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1616 out_msg.accept(), &username));
1617 EXPECT_TRUE(out_msg.get() != NULL);
1618 EXPECT_EQ("", username);
1619
1620 // BINDING-RESPONSE without username. Should be tolerated as well.
1621 in_msg.reset(CreateStunMessage(STUN_BINDING_RESPONSE));
1622 in_msg->AddAttribute(
1623 new StunAddressAttribute(STUN_ATTR_MAPPED_ADDRESS, kLocalAddr2));
1624 WriteStunMessage(in_msg.get(), buf.get());
1625 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1626 out_msg.accept(), &username));
1627 EXPECT_TRUE(out_msg.get() != NULL);
1628 EXPECT_EQ("", username);
1629
1630 // BINDING-ERROR-RESPONSE with username and error code.
1631 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_ERROR_RESPONSE,
1632 "rfraglfrag"));
1633 in_msg->AddAttribute(new StunErrorCodeAttribute(STUN_ATTR_ERROR_CODE,
1634 STUN_ERROR_SERVER_ERROR_AS_GICE, STUN_ERROR_REASON_SERVER_ERROR));
1635 WriteStunMessage(in_msg.get(), buf.get());
1636 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1637 out_msg.accept(), &username));
1638 ASSERT_TRUE(out_msg.get() != NULL);
1639 EXPECT_EQ("", username);
1640 ASSERT_TRUE(out_msg->GetErrorCode() != NULL);
1641 // GetStunMessage doesn't unmunge the GICE error code (happens downstream).
1642 EXPECT_EQ(STUN_ERROR_SERVER_ERROR_AS_GICE, out_msg->GetErrorCode()->code());
1643 EXPECT_EQ(std::string(STUN_ERROR_REASON_SERVER_ERROR),
1644 out_msg->GetErrorCode()->reason());
1645}
1646
1647// Test handling STUN messages in ICE format.
1648TEST_F(PortTest, TestHandleStunMessageAsIce) {
1649 // Our port will act as the "remote" port.
1650 talk_base::scoped_ptr<TestPort> port(
1651 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1652 port->SetIceProtocolType(ICEPROTO_RFC5245);
1653
1654 talk_base::scoped_ptr<IceMessage> in_msg, out_msg;
1655 talk_base::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
1656 talk_base::SocketAddress addr(kLocalAddr1);
1657 std::string username;
1658
1659 // BINDING-REQUEST from local to remote with valid ICE username,
1660 // MESSAGE-INTEGRITY, and FINGERPRINT.
1661 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
1662 "rfrag:lfrag"));
1663 in_msg->AddMessageIntegrity("rpass");
1664 in_msg->AddFingerprint();
1665 WriteStunMessage(in_msg.get(), buf.get());
1666 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1667 out_msg.accept(), &username));
1668 EXPECT_TRUE(out_msg.get() != NULL);
1669 EXPECT_EQ("lfrag", username);
1670
1671 // BINDING-RESPONSE without username, with MESSAGE-INTEGRITY and FINGERPRINT.
1672 in_msg.reset(CreateStunMessage(STUN_BINDING_RESPONSE));
1673 in_msg->AddAttribute(
1674 new StunXorAddressAttribute(STUN_ATTR_XOR_MAPPED_ADDRESS, kLocalAddr2));
1675 in_msg->AddMessageIntegrity("rpass");
1676 in_msg->AddFingerprint();
1677 WriteStunMessage(in_msg.get(), buf.get());
1678 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1679 out_msg.accept(), &username));
1680 EXPECT_TRUE(out_msg.get() != NULL);
1681 EXPECT_EQ("", username);
1682
1683 // BINDING-ERROR-RESPONSE without username, with error, M-I, and FINGERPRINT.
1684 in_msg.reset(CreateStunMessage(STUN_BINDING_ERROR_RESPONSE));
1685 in_msg->AddAttribute(new StunErrorCodeAttribute(STUN_ATTR_ERROR_CODE,
1686 STUN_ERROR_SERVER_ERROR, STUN_ERROR_REASON_SERVER_ERROR));
1687 in_msg->AddFingerprint();
1688 WriteStunMessage(in_msg.get(), buf.get());
1689 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1690 out_msg.accept(), &username));
1691 EXPECT_TRUE(out_msg.get() != NULL);
1692 EXPECT_EQ("", username);
1693 ASSERT_TRUE(out_msg->GetErrorCode() != NULL);
1694 EXPECT_EQ(STUN_ERROR_SERVER_ERROR, out_msg->GetErrorCode()->code());
1695 EXPECT_EQ(std::string(STUN_ERROR_REASON_SERVER_ERROR),
1696 out_msg->GetErrorCode()->reason());
1697}
1698
mallinath@webrtc.org67ee6b92014-02-03 16:57:16 +00001699// This test verifies port can handle ICE messages in Hybrid mode and switches
1700// ICEPROTO_RFC5245 mode after successfully handling the message.
1701TEST_F(PortTest, TestHandleStunMessageAsIceInHybridMode) {
1702 // Our port will act as the "remote" port.
1703 talk_base::scoped_ptr<TestPort> port(
1704 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1705 port->SetIceProtocolType(ICEPROTO_HYBRID);
1706
1707 talk_base::scoped_ptr<IceMessage> in_msg, out_msg;
1708 talk_base::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
1709 talk_base::SocketAddress addr(kLocalAddr1);
1710 std::string username;
1711
1712 // BINDING-REQUEST from local to remote with valid ICE username,
1713 // MESSAGE-INTEGRITY, and FINGERPRINT.
1714 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
1715 "rfrag:lfrag"));
1716 in_msg->AddMessageIntegrity("rpass");
1717 in_msg->AddFingerprint();
1718 WriteStunMessage(in_msg.get(), buf.get());
1719 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1720 out_msg.accept(), &username));
1721 EXPECT_TRUE(out_msg.get() != NULL);
1722 EXPECT_EQ("lfrag", username);
1723 EXPECT_EQ(ICEPROTO_RFC5245, port->IceProtocol());
1724}
1725
1726// This test verifies port can handle GICE messages in Hybrid mode and switches
1727// ICEPROTO_GOOGLE mode after successfully handling the message.
1728TEST_F(PortTest, TestHandleStunMessageAsGiceInHybridMode) {
1729 // Our port will act as the "remote" port.
1730 talk_base::scoped_ptr<TestPort> port(
1731 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1732 port->SetIceProtocolType(ICEPROTO_HYBRID);
1733
1734 talk_base::scoped_ptr<IceMessage> in_msg, out_msg;
1735 talk_base::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
1736 talk_base::SocketAddress addr(kLocalAddr1);
1737 std::string username;
1738
1739 // BINDING-REQUEST from local to remote with valid GICE username and no M-I.
1740 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
1741 "rfraglfrag"));
1742 WriteStunMessage(in_msg.get(), buf.get());
1743 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1744 out_msg.accept(), &username));
1745 EXPECT_TRUE(out_msg.get() != NULL); // Succeeds, since this is GICE.
1746 EXPECT_EQ("lfrag", username);
1747 EXPECT_EQ(ICEPROTO_GOOGLE, port->IceProtocol());
1748}
1749
1750// Verify port is not switched out of RFC5245 mode if GICE message is received
1751// in that mode.
1752TEST_F(PortTest, TestHandleStunMessageAsGiceInIceMode) {
1753 // Our port will act as the "remote" port.
1754 talk_base::scoped_ptr<TestPort> port(
1755 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1756 port->SetIceProtocolType(ICEPROTO_RFC5245);
1757
1758 talk_base::scoped_ptr<IceMessage> in_msg, out_msg;
1759 talk_base::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
1760 talk_base::SocketAddress addr(kLocalAddr1);
1761 std::string username;
1762
1763 // BINDING-REQUEST from local to remote with valid GICE username and no M-I.
1764 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
1765 "rfraglfrag"));
1766 WriteStunMessage(in_msg.get(), buf.get());
1767 // Should fail as there is no MI and fingerprint.
1768 EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1769 out_msg.accept(), &username));
1770 EXPECT_EQ(ICEPROTO_RFC5245, port->IceProtocol());
1771}
1772
1773
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001774// Tests handling of GICE binding requests with missing or incorrect usernames.
1775TEST_F(PortTest, TestHandleStunMessageAsGiceBadUsername) {
1776 talk_base::scoped_ptr<TestPort> port(
1777 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1778 port->SetIceProtocolType(ICEPROTO_GOOGLE);
1779
1780 talk_base::scoped_ptr<IceMessage> in_msg, out_msg;
1781 talk_base::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
1782 talk_base::SocketAddress addr(kLocalAddr1);
1783 std::string username;
1784
1785 // BINDING-REQUEST with no username.
1786 in_msg.reset(CreateStunMessage(STUN_BINDING_REQUEST));
1787 WriteStunMessage(in_msg.get(), buf.get());
1788 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1789 out_msg.accept(), &username));
1790 EXPECT_TRUE(out_msg.get() == NULL);
1791 EXPECT_EQ("", username);
1792 EXPECT_EQ(STUN_ERROR_BAD_REQUEST_AS_GICE, port->last_stun_error_code());
1793
1794 // BINDING-REQUEST with empty username.
1795 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST, ""));
1796 WriteStunMessage(in_msg.get(), buf.get());
1797 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1798 out_msg.accept(), &username));
1799 EXPECT_TRUE(out_msg.get() == NULL);
1800 EXPECT_EQ("", username);
1801 EXPECT_EQ(STUN_ERROR_UNAUTHORIZED_AS_GICE, port->last_stun_error_code());
1802
1803 // BINDING-REQUEST with too-short username.
1804 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST, "lfra"));
1805 WriteStunMessage(in_msg.get(), buf.get());
1806 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1807 out_msg.accept(), &username));
1808 EXPECT_TRUE(out_msg.get() == NULL);
1809 EXPECT_EQ("", username);
1810 EXPECT_EQ(STUN_ERROR_UNAUTHORIZED_AS_GICE, port->last_stun_error_code());
1811
1812 // BINDING-REQUEST with reversed username.
1813 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
1814 "lfragrfrag"));
1815 WriteStunMessage(in_msg.get(), buf.get());
1816 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1817 out_msg.accept(), &username));
1818 EXPECT_TRUE(out_msg.get() == NULL);
1819 EXPECT_EQ("", username);
1820 EXPECT_EQ(STUN_ERROR_UNAUTHORIZED_AS_GICE, port->last_stun_error_code());
1821
1822 // BINDING-REQUEST with garbage username.
1823 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
1824 "abcdefgh"));
1825 WriteStunMessage(in_msg.get(), buf.get());
1826 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1827 out_msg.accept(), &username));
1828 EXPECT_TRUE(out_msg.get() == NULL);
1829 EXPECT_EQ("", username);
1830 EXPECT_EQ(STUN_ERROR_UNAUTHORIZED_AS_GICE, port->last_stun_error_code());
1831}
1832
1833// Tests handling of ICE binding requests with missing or incorrect usernames.
1834TEST_F(PortTest, TestHandleStunMessageAsIceBadUsername) {
1835 talk_base::scoped_ptr<TestPort> port(
1836 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1837 port->SetIceProtocolType(ICEPROTO_RFC5245);
1838
1839 talk_base::scoped_ptr<IceMessage> in_msg, out_msg;
1840 talk_base::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
1841 talk_base::SocketAddress addr(kLocalAddr1);
1842 std::string username;
1843
1844 // BINDING-REQUEST with no username.
1845 in_msg.reset(CreateStunMessage(STUN_BINDING_REQUEST));
1846 in_msg->AddMessageIntegrity("rpass");
1847 in_msg->AddFingerprint();
1848 WriteStunMessage(in_msg.get(), buf.get());
1849 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1850 out_msg.accept(), &username));
1851 EXPECT_TRUE(out_msg.get() == NULL);
1852 EXPECT_EQ("", username);
1853 EXPECT_EQ(STUN_ERROR_BAD_REQUEST, port->last_stun_error_code());
1854
1855 // BINDING-REQUEST with empty username.
1856 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST, ""));
1857 in_msg->AddMessageIntegrity("rpass");
1858 in_msg->AddFingerprint();
1859 WriteStunMessage(in_msg.get(), buf.get());
1860 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1861 out_msg.accept(), &username));
1862 EXPECT_TRUE(out_msg.get() == NULL);
1863 EXPECT_EQ("", username);
1864 EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
1865
1866 // BINDING-REQUEST with too-short username.
1867 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST, "rfra"));
1868 in_msg->AddMessageIntegrity("rpass");
1869 in_msg->AddFingerprint();
1870 WriteStunMessage(in_msg.get(), buf.get());
1871 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1872 out_msg.accept(), &username));
1873 EXPECT_TRUE(out_msg.get() == NULL);
1874 EXPECT_EQ("", username);
1875 EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
1876
1877 // BINDING-REQUEST with reversed username.
1878 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
1879 "lfrag:rfrag"));
1880 in_msg->AddMessageIntegrity("rpass");
1881 in_msg->AddFingerprint();
1882 WriteStunMessage(in_msg.get(), buf.get());
1883 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1884 out_msg.accept(), &username));
1885 EXPECT_TRUE(out_msg.get() == NULL);
1886 EXPECT_EQ("", username);
1887 EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
1888
1889 // BINDING-REQUEST with garbage username.
1890 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
1891 "abcd:efgh"));
1892 in_msg->AddMessageIntegrity("rpass");
1893 in_msg->AddFingerprint();
1894 WriteStunMessage(in_msg.get(), buf.get());
1895 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1896 out_msg.accept(), &username));
1897 EXPECT_TRUE(out_msg.get() == NULL);
1898 EXPECT_EQ("", username);
1899 EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
1900}
1901
1902// Test handling STUN messages (as ICE) with missing or malformed M-I.
1903TEST_F(PortTest, TestHandleStunMessageAsIceBadMessageIntegrity) {
1904 // Our port will act as the "remote" port.
1905 talk_base::scoped_ptr<TestPort> port(
1906 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1907 port->SetIceProtocolType(ICEPROTO_RFC5245);
1908
1909 talk_base::scoped_ptr<IceMessage> in_msg, out_msg;
1910 talk_base::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
1911 talk_base::SocketAddress addr(kLocalAddr1);
1912 std::string username;
1913
1914 // BINDING-REQUEST from local to remote with valid ICE username and
1915 // FINGERPRINT, but no MESSAGE-INTEGRITY.
1916 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
1917 "rfrag:lfrag"));
1918 in_msg->AddFingerprint();
1919 WriteStunMessage(in_msg.get(), buf.get());
1920 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1921 out_msg.accept(), &username));
1922 EXPECT_TRUE(out_msg.get() == NULL);
1923 EXPECT_EQ("", username);
1924 EXPECT_EQ(STUN_ERROR_BAD_REQUEST, port->last_stun_error_code());
1925
1926 // BINDING-REQUEST from local to remote with valid ICE username and
1927 // FINGERPRINT, but invalid MESSAGE-INTEGRITY.
1928 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
1929 "rfrag:lfrag"));
1930 in_msg->AddMessageIntegrity("invalid");
1931 in_msg->AddFingerprint();
1932 WriteStunMessage(in_msg.get(), buf.get());
1933 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1934 out_msg.accept(), &username));
1935 EXPECT_TRUE(out_msg.get() == NULL);
1936 EXPECT_EQ("", username);
1937 EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
1938
1939 // TODO: BINDING-RESPONSES and BINDING-ERROR-RESPONSES are checked
1940 // by the Connection, not the Port, since they require the remote username.
1941 // Change this test to pass in data via Connection::OnReadPacket instead.
1942}
1943
1944// Test handling STUN messages (as ICE) with missing or malformed FINGERPRINT.
1945TEST_F(PortTest, TestHandleStunMessageAsIceBadFingerprint) {
1946 // Our port will act as the "remote" port.
1947 talk_base::scoped_ptr<TestPort> port(
1948 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1949 port->SetIceProtocolType(ICEPROTO_RFC5245);
1950
1951 talk_base::scoped_ptr<IceMessage> in_msg, out_msg;
1952 talk_base::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
1953 talk_base::SocketAddress addr(kLocalAddr1);
1954 std::string username;
1955
1956 // BINDING-REQUEST from local to remote with valid ICE username and
1957 // MESSAGE-INTEGRITY, but no FINGERPRINT; GetStunMessage should fail.
1958 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
1959 "rfrag:lfrag"));
1960 in_msg->AddMessageIntegrity("rpass");
1961 WriteStunMessage(in_msg.get(), buf.get());
1962 EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1963 out_msg.accept(), &username));
1964 EXPECT_EQ(0, port->last_stun_error_code());
1965
1966 // Now, add a fingerprint, but munge the message so it's not valid.
1967 in_msg->AddFingerprint();
1968 in_msg->SetTransactionID("TESTTESTBADD");
1969 WriteStunMessage(in_msg.get(), buf.get());
1970 EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1971 out_msg.accept(), &username));
1972 EXPECT_EQ(0, port->last_stun_error_code());
1973
1974 // Valid BINDING-RESPONSE, except no FINGERPRINT.
1975 in_msg.reset(CreateStunMessage(STUN_BINDING_RESPONSE));
1976 in_msg->AddAttribute(
1977 new StunXorAddressAttribute(STUN_ATTR_XOR_MAPPED_ADDRESS, kLocalAddr2));
1978 in_msg->AddMessageIntegrity("rpass");
1979 WriteStunMessage(in_msg.get(), buf.get());
1980 EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1981 out_msg.accept(), &username));
1982 EXPECT_EQ(0, port->last_stun_error_code());
1983
1984 // Now, add a fingerprint, but munge the message so it's not valid.
1985 in_msg->AddFingerprint();
1986 in_msg->SetTransactionID("TESTTESTBADD");
1987 WriteStunMessage(in_msg.get(), buf.get());
1988 EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1989 out_msg.accept(), &username));
1990 EXPECT_EQ(0, port->last_stun_error_code());
1991
1992 // Valid BINDING-ERROR-RESPONSE, except no FINGERPRINT.
1993 in_msg.reset(CreateStunMessage(STUN_BINDING_ERROR_RESPONSE));
1994 in_msg->AddAttribute(new StunErrorCodeAttribute(STUN_ATTR_ERROR_CODE,
1995 STUN_ERROR_SERVER_ERROR, STUN_ERROR_REASON_SERVER_ERROR));
1996 in_msg->AddMessageIntegrity("rpass");
1997 WriteStunMessage(in_msg.get(), buf.get());
1998 EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1999 out_msg.accept(), &username));
2000 EXPECT_EQ(0, port->last_stun_error_code());
2001
2002 // Now, add a fingerprint, but munge the message so it's not valid.
2003 in_msg->AddFingerprint();
2004 in_msg->SetTransactionID("TESTTESTBADD");
2005 WriteStunMessage(in_msg.get(), buf.get());
2006 EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
2007 out_msg.accept(), &username));
2008 EXPECT_EQ(0, port->last_stun_error_code());
2009}
2010
2011// Test handling of STUN binding indication messages (as ICE). STUN binding
2012// indications are allowed only to the connection which is in read mode.
2013TEST_F(PortTest, TestHandleStunBindingIndication) {
2014 talk_base::scoped_ptr<TestPort> lport(
2015 CreateTestPort(kLocalAddr2, "lfrag", "lpass"));
2016 lport->SetIceProtocolType(ICEPROTO_RFC5245);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00002017 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
2018 lport->SetIceTiebreaker(kTiebreaker1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002019
2020 // Verifying encoding and decoding STUN indication message.
2021 talk_base::scoped_ptr<IceMessage> in_msg, out_msg;
2022 talk_base::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
2023 talk_base::SocketAddress addr(kLocalAddr1);
2024 std::string username;
2025
2026 in_msg.reset(CreateStunMessage(STUN_BINDING_INDICATION));
2027 in_msg->AddFingerprint();
2028 WriteStunMessage(in_msg.get(), buf.get());
2029 EXPECT_TRUE(lport->GetStunMessage(buf->Data(), buf->Length(), addr,
2030 out_msg.accept(), &username));
2031 EXPECT_TRUE(out_msg.get() != NULL);
2032 EXPECT_EQ(out_msg->type(), STUN_BINDING_INDICATION);
2033 EXPECT_EQ("", username);
2034
2035 // Verify connection can handle STUN indication and updates
2036 // last_ping_received.
2037 talk_base::scoped_ptr<TestPort> rport(
2038 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
2039 rport->SetIceProtocolType(ICEPROTO_RFC5245);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00002040 rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
2041 rport->SetIceTiebreaker(kTiebreaker2);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002042
2043 lport->PrepareAddress();
2044 rport->PrepareAddress();
2045 ASSERT_FALSE(lport->Candidates().empty());
2046 ASSERT_FALSE(rport->Candidates().empty());
2047
2048 Connection* lconn = lport->CreateConnection(rport->Candidates()[0],
2049 Port::ORIGIN_MESSAGE);
2050 Connection* rconn = rport->CreateConnection(lport->Candidates()[0],
2051 Port::ORIGIN_MESSAGE);
2052 rconn->Ping(0);
2053
2054 ASSERT_TRUE_WAIT(rport->last_stun_msg() != NULL, 1000);
2055 IceMessage* msg = rport->last_stun_msg();
2056 EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
2057 // Send rport binding request to lport.
2058 lconn->OnReadPacket(rport->last_stun_buf()->Data(),
wu@webrtc.orga9890802013-12-13 00:21:03 +00002059 rport->last_stun_buf()->Length(),
2060 talk_base::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002061 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, 1000);
2062 EXPECT_EQ(STUN_BINDING_RESPONSE, lport->last_stun_msg()->type());
2063 uint32 last_ping_received1 = lconn->last_ping_received();
2064
2065 // Adding a delay of 100ms.
2066 talk_base::Thread::Current()->ProcessMessages(100);
2067 // Pinging lconn using stun indication message.
wu@webrtc.orga9890802013-12-13 00:21:03 +00002068 lconn->OnReadPacket(buf->Data(), buf->Length(), talk_base::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002069 uint32 last_ping_received2 = lconn->last_ping_received();
2070 EXPECT_GT(last_ping_received2, last_ping_received1);
2071}
2072
2073TEST_F(PortTest, TestComputeCandidatePriority) {
2074 talk_base::scoped_ptr<TestPort> port(
2075 CreateTestPort(kLocalAddr1, "name", "pass"));
2076 port->set_type_preference(90);
2077 port->set_component(177);
2078 port->AddCandidateAddress(SocketAddress("192.168.1.4", 1234));
2079 port->AddCandidateAddress(SocketAddress("2001:db8::1234", 1234));
2080 port->AddCandidateAddress(SocketAddress("fc12:3456::1234", 1234));
2081 port->AddCandidateAddress(SocketAddress("::ffff:192.168.1.4", 1234));
2082 port->AddCandidateAddress(SocketAddress("::192.168.1.4", 1234));
2083 port->AddCandidateAddress(SocketAddress("2002::1234:5678", 1234));
2084 port->AddCandidateAddress(SocketAddress("2001::1234:5678", 1234));
2085 port->AddCandidateAddress(SocketAddress("fecf::1234:5678", 1234));
2086 port->AddCandidateAddress(SocketAddress("3ffe::1234:5678", 1234));
2087 // These should all be:
2088 // (90 << 24) | ([rfc3484 pref value] << 8) | (256 - 177)
2089 uint32 expected_priority_v4 = 1509957199U;
2090 uint32 expected_priority_v6 = 1509959759U;
2091 uint32 expected_priority_ula = 1509962319U;
2092 uint32 expected_priority_v4mapped = expected_priority_v4;
2093 uint32 expected_priority_v4compat = 1509949775U;
2094 uint32 expected_priority_6to4 = 1509954639U;
2095 uint32 expected_priority_teredo = 1509952079U;
2096 uint32 expected_priority_sitelocal = 1509949775U;
2097 uint32 expected_priority_6bone = 1509949775U;
2098 ASSERT_EQ(expected_priority_v4, port->Candidates()[0].priority());
2099 ASSERT_EQ(expected_priority_v6, port->Candidates()[1].priority());
2100 ASSERT_EQ(expected_priority_ula, port->Candidates()[2].priority());
2101 ASSERT_EQ(expected_priority_v4mapped, port->Candidates()[3].priority());
2102 ASSERT_EQ(expected_priority_v4compat, port->Candidates()[4].priority());
2103 ASSERT_EQ(expected_priority_6to4, port->Candidates()[5].priority());
2104 ASSERT_EQ(expected_priority_teredo, port->Candidates()[6].priority());
2105 ASSERT_EQ(expected_priority_sitelocal, port->Candidates()[7].priority());
2106 ASSERT_EQ(expected_priority_6bone, port->Candidates()[8].priority());
2107}
2108
2109TEST_F(PortTest, TestPortProxyProperties) {
2110 talk_base::scoped_ptr<TestPort> port(
2111 CreateTestPort(kLocalAddr1, "name", "pass"));
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00002112 port->SetIceRole(cricket::ICEROLE_CONTROLLING);
2113 port->SetIceTiebreaker(kTiebreaker1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002114
2115 // Create a proxy port.
2116 talk_base::scoped_ptr<PortProxy> proxy(new PortProxy());
2117 proxy->set_impl(port.get());
2118 EXPECT_EQ(port->Type(), proxy->Type());
2119 EXPECT_EQ(port->Network(), proxy->Network());
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00002120 EXPECT_EQ(port->GetIceRole(), proxy->GetIceRole());
2121 EXPECT_EQ(port->IceTiebreaker(), proxy->IceTiebreaker());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002122}
2123
2124// In the case of shared socket, one port may be shared by local and stun.
2125// Test that candidates with different types will have different foundation.
2126TEST_F(PortTest, TestFoundation) {
2127 talk_base::scoped_ptr<TestPort> testport(
2128 CreateTestPort(kLocalAddr1, "name", "pass"));
2129 testport->AddCandidateAddress(kLocalAddr1, kLocalAddr1,
2130 LOCAL_PORT_TYPE,
2131 cricket::ICE_TYPE_PREFERENCE_HOST, false);
2132 testport->AddCandidateAddress(kLocalAddr2, kLocalAddr1,
2133 STUN_PORT_TYPE,
2134 cricket::ICE_TYPE_PREFERENCE_SRFLX, true);
2135 EXPECT_NE(testport->Candidates()[0].foundation(),
2136 testport->Candidates()[1].foundation());
2137}
2138
2139// This test verifies the foundation of different types of ICE candidates.
2140TEST_F(PortTest, TestCandidateFoundation) {
2141 talk_base::scoped_ptr<talk_base::NATServer> nat_server(
2142 CreateNatServer(kNatAddr1, NAT_OPEN_CONE));
2143 talk_base::scoped_ptr<UDPPort> udpport1(CreateUdpPort(kLocalAddr1));
2144 udpport1->PrepareAddress();
2145 talk_base::scoped_ptr<UDPPort> udpport2(CreateUdpPort(kLocalAddr1));
2146 udpport2->PrepareAddress();
2147 EXPECT_EQ(udpport1->Candidates()[0].foundation(),
2148 udpport2->Candidates()[0].foundation());
2149 talk_base::scoped_ptr<TCPPort> tcpport1(CreateTcpPort(kLocalAddr1));
2150 tcpport1->PrepareAddress();
2151 talk_base::scoped_ptr<TCPPort> tcpport2(CreateTcpPort(kLocalAddr1));
2152 tcpport2->PrepareAddress();
2153 EXPECT_EQ(tcpport1->Candidates()[0].foundation(),
2154 tcpport2->Candidates()[0].foundation());
2155 talk_base::scoped_ptr<Port> stunport(
2156 CreateStunPort(kLocalAddr1, nat_socket_factory1()));
2157 stunport->PrepareAddress();
2158 ASSERT_EQ_WAIT(1U, stunport->Candidates().size(), kTimeout);
2159 EXPECT_NE(tcpport1->Candidates()[0].foundation(),
2160 stunport->Candidates()[0].foundation());
2161 EXPECT_NE(tcpport2->Candidates()[0].foundation(),
2162 stunport->Candidates()[0].foundation());
2163 EXPECT_NE(udpport1->Candidates()[0].foundation(),
2164 stunport->Candidates()[0].foundation());
2165 EXPECT_NE(udpport2->Candidates()[0].foundation(),
2166 stunport->Candidates()[0].foundation());
2167 // Verify GTURN candidate foundation.
2168 talk_base::scoped_ptr<RelayPort> relayport(
2169 CreateGturnPort(kLocalAddr1));
2170 relayport->AddServerAddress(
2171 cricket::ProtocolAddress(kRelayUdpIntAddr, cricket::PROTO_UDP));
2172 relayport->PrepareAddress();
2173 ASSERT_EQ_WAIT(1U, relayport->Candidates().size(), kTimeout);
2174 EXPECT_NE(udpport1->Candidates()[0].foundation(),
2175 relayport->Candidates()[0].foundation());
2176 EXPECT_NE(udpport2->Candidates()[0].foundation(),
2177 relayport->Candidates()[0].foundation());
2178 // Verifying TURN candidate foundation.
buildbot@webrtc.orgff90ed62014-04-25 21:12:10 +00002179 talk_base::scoped_ptr<Port> turnport1(CreateTurnPort(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002180 kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
buildbot@webrtc.orgff90ed62014-04-25 21:12:10 +00002181 turnport1->PrepareAddress();
buildbot@webrtc.orgcd846dd2014-05-13 22:58:27 +00002182 ASSERT_EQ_WAIT(1U, turnport1->Candidates().size(), kTimeout);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002183 EXPECT_NE(udpport1->Candidates()[0].foundation(),
buildbot@webrtc.orgcd846dd2014-05-13 22:58:27 +00002184 turnport1->Candidates()[0].foundation());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002185 EXPECT_NE(udpport2->Candidates()[0].foundation(),
buildbot@webrtc.orgcd846dd2014-05-13 22:58:27 +00002186 turnport1->Candidates()[0].foundation());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002187 EXPECT_NE(stunport->Candidates()[0].foundation(),
buildbot@webrtc.orgff90ed62014-04-25 21:12:10 +00002188 turnport1->Candidates()[0].foundation());
2189 talk_base::scoped_ptr<Port> turnport2(CreateTurnPort(
2190 kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
2191 turnport2->PrepareAddress();
buildbot@webrtc.orgcd846dd2014-05-13 22:58:27 +00002192 ASSERT_EQ_WAIT(1U, turnport2->Candidates().size(), kTimeout);
2193 EXPECT_EQ(turnport1->Candidates()[0].foundation(),
2194 turnport2->Candidates()[0].foundation());
buildbot@webrtc.orgff90ed62014-04-25 21:12:10 +00002195
2196 // Running a second turn server, to get different base IP address.
2197 SocketAddress kTurnUdpIntAddr2("99.99.98.4", STUN_SERVER_PORT);
2198 SocketAddress kTurnUdpExtAddr2("99.99.98.5", 0);
2199 TestTurnServer turn_server2(
2200 talk_base::Thread::Current(), kTurnUdpIntAddr2, kTurnUdpExtAddr2);
2201 talk_base::scoped_ptr<Port> turnport3(CreateTurnPort(
2202 kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP,
2203 kTurnUdpIntAddr2));
2204 turnport3->PrepareAddress();
buildbot@webrtc.orgcd846dd2014-05-13 22:58:27 +00002205 ASSERT_EQ_WAIT(1U, turnport3->Candidates().size(), kTimeout);
2206 EXPECT_NE(turnport3->Candidates()[0].foundation(),
2207 turnport2->Candidates()[0].foundation());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002208}
2209
2210// This test verifies the related addresses of different types of
2211// ICE candiates.
2212TEST_F(PortTest, TestCandidateRelatedAddress) {
2213 talk_base::scoped_ptr<talk_base::NATServer> nat_server(
2214 CreateNatServer(kNatAddr1, NAT_OPEN_CONE));
2215 talk_base::scoped_ptr<UDPPort> udpport(CreateUdpPort(kLocalAddr1));
2216 udpport->PrepareAddress();
2217 // For UDPPort, related address will be empty.
2218 EXPECT_TRUE(udpport->Candidates()[0].related_address().IsNil());
2219 // Testing related address for stun candidates.
2220 // For stun candidate related address must be equal to the base
2221 // socket address.
2222 talk_base::scoped_ptr<StunPort> stunport(
2223 CreateStunPort(kLocalAddr1, nat_socket_factory1()));
2224 stunport->PrepareAddress();
2225 ASSERT_EQ_WAIT(1U, stunport->Candidates().size(), kTimeout);
2226 // Check STUN candidate address.
2227 EXPECT_EQ(stunport->Candidates()[0].address().ipaddr(),
2228 kNatAddr1.ipaddr());
2229 // Check STUN candidate related address.
2230 EXPECT_EQ(stunport->Candidates()[0].related_address(),
2231 stunport->GetLocalAddress());
2232 // Verifying the related address for the GTURN candidates.
2233 // NOTE: In case of GTURN related address will be equal to the mapped
2234 // address, but address(mapped) will not be XOR.
2235 talk_base::scoped_ptr<RelayPort> relayport(
2236 CreateGturnPort(kLocalAddr1));
2237 relayport->AddServerAddress(
2238 cricket::ProtocolAddress(kRelayUdpIntAddr, cricket::PROTO_UDP));
2239 relayport->PrepareAddress();
2240 ASSERT_EQ_WAIT(1U, relayport->Candidates().size(), kTimeout);
2241 // For Gturn related address is set to "0.0.0.0:0"
2242 EXPECT_EQ(talk_base::SocketAddress(),
2243 relayport->Candidates()[0].related_address());
2244 // Verifying the related address for TURN candidate.
2245 // For TURN related address must be equal to the mapped address.
2246 talk_base::scoped_ptr<Port> turnport(CreateTurnPort(
2247 kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
2248 turnport->PrepareAddress();
buildbot@webrtc.orgcd846dd2014-05-13 22:58:27 +00002249 ASSERT_EQ_WAIT(1U, turnport->Candidates().size(), kTimeout);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002250 EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
buildbot@webrtc.orgcd846dd2014-05-13 22:58:27 +00002251 turnport->Candidates()[0].address().ipaddr());
buildbot@webrtc.org8a548442014-05-09 18:10:55 +00002252 EXPECT_EQ(kNatAddr1.ipaddr(),
buildbot@webrtc.orgcd846dd2014-05-13 22:58:27 +00002253 turnport->Candidates()[0].related_address().ipaddr());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002254}
2255
2256// Test priority value overflow handling when preference is set to 3.
2257TEST_F(PortTest, TestCandidatePreference) {
2258 cricket::Candidate cand1;
2259 cand1.set_preference(3);
2260 cricket::Candidate cand2;
2261 cand2.set_preference(1);
2262 EXPECT_TRUE(cand1.preference() > cand2.preference());
2263}
2264
2265// Test the Connection priority is calculated correctly.
2266TEST_F(PortTest, TestConnectionPriority) {
2267 talk_base::scoped_ptr<TestPort> lport(
2268 CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
2269 lport->set_type_preference(cricket::ICE_TYPE_PREFERENCE_HOST);
2270 talk_base::scoped_ptr<TestPort> rport(
2271 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
2272 rport->set_type_preference(cricket::ICE_TYPE_PREFERENCE_RELAY);
2273 lport->set_component(123);
2274 lport->AddCandidateAddress(SocketAddress("192.168.1.4", 1234));
2275 rport->set_component(23);
2276 rport->AddCandidateAddress(SocketAddress("10.1.1.100", 1234));
2277
2278 EXPECT_EQ(0x7E001E85U, lport->Candidates()[0].priority());
2279 EXPECT_EQ(0x2001EE9U, rport->Candidates()[0].priority());
2280
2281 // RFC 5245
2282 // pair priority = 2^32*MIN(G,D) + 2*MAX(G,D) + (G>D?1:0)
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00002283 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
2284 rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002285 Connection* lconn = lport->CreateConnection(
2286 rport->Candidates()[0], Port::ORIGIN_MESSAGE);
2287#if defined(WIN32)
2288 EXPECT_EQ(0x2001EE9FC003D0BU, lconn->priority());
2289#else
2290 EXPECT_EQ(0x2001EE9FC003D0BLLU, lconn->priority());
2291#endif
2292
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00002293 lport->SetIceRole(cricket::ICEROLE_CONTROLLED);
2294 rport->SetIceRole(cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002295 Connection* rconn = rport->CreateConnection(
2296 lport->Candidates()[0], Port::ORIGIN_MESSAGE);
2297#if defined(WIN32)
2298 EXPECT_EQ(0x2001EE9FC003D0AU, rconn->priority());
2299#else
2300 EXPECT_EQ(0x2001EE9FC003D0ALLU, rconn->priority());
2301#endif
2302}
2303
2304TEST_F(PortTest, TestWritableState) {
2305 UDPPort* port1 = CreateUdpPort(kLocalAddr1);
2306 UDPPort* port2 = CreateUdpPort(kLocalAddr2);
2307
2308 // Set up channels.
2309 TestChannel ch1(port1, port2);
2310 TestChannel ch2(port2, port1);
2311
2312 // Acquire addresses.
2313 ch1.Start();
2314 ch2.Start();
2315 ASSERT_EQ_WAIT(1, ch1.complete_count(), kTimeout);
2316 ASSERT_EQ_WAIT(1, ch2.complete_count(), kTimeout);
2317
2318 // Send a ping from src to dst.
2319 ch1.CreateConnection();
2320 ASSERT_TRUE(ch1.conn() != NULL);
2321 EXPECT_EQ(Connection::STATE_WRITE_INIT, ch1.conn()->write_state());
2322 EXPECT_TRUE_WAIT(ch1.conn()->connected(), kTimeout); // for TCP connect
2323 ch1.Ping();
2324 WAIT(!ch2.remote_address().IsNil(), kTimeout);
2325
2326 // Data should be unsendable until the connection is accepted.
2327 char data[] = "abcd";
2328 int data_size = ARRAY_SIZE(data);
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00002329 talk_base::PacketOptions options;
2330 EXPECT_EQ(SOCKET_ERROR, ch1.conn()->Send(data, data_size, options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002331
2332 // Accept the connection to return the binding response, transition to
2333 // writable, and allow data to be sent.
2334 ch2.AcceptConnection();
2335 EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch1.conn()->write_state(),
2336 kTimeout);
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00002337 EXPECT_EQ(data_size, ch1.conn()->Send(data, data_size, options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002338
2339 // Ask the connection to update state as if enough time has passed to lose
2340 // full writability and 5 pings went unresponded to. We'll accomplish the
2341 // latter by sending pings but not pumping messages.
2342 for (uint32 i = 1; i <= CONNECTION_WRITE_CONNECT_FAILURES; ++i) {
2343 ch1.Ping(i);
2344 }
2345 uint32 unreliable_timeout_delay = CONNECTION_WRITE_CONNECT_TIMEOUT + 500u;
2346 ch1.conn()->UpdateState(unreliable_timeout_delay);
2347 EXPECT_EQ(Connection::STATE_WRITE_UNRELIABLE, ch1.conn()->write_state());
2348
2349 // Data should be able to be sent in this state.
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00002350 EXPECT_EQ(data_size, ch1.conn()->Send(data, data_size, options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002351
2352 // And now allow the other side to process the pings and send binding
2353 // responses.
2354 EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch1.conn()->write_state(),
2355 kTimeout);
2356
2357 // Wait long enough for a full timeout (past however long we've already
2358 // waited).
2359 for (uint32 i = 1; i <= CONNECTION_WRITE_CONNECT_FAILURES; ++i) {
2360 ch1.Ping(unreliable_timeout_delay + i);
2361 }
2362 ch1.conn()->UpdateState(unreliable_timeout_delay + CONNECTION_WRITE_TIMEOUT +
2363 500u);
2364 EXPECT_EQ(Connection::STATE_WRITE_TIMEOUT, ch1.conn()->write_state());
2365
2366 // Now that the connection has completely timed out, data send should fail.
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00002367 EXPECT_EQ(SOCKET_ERROR, ch1.conn()->Send(data, data_size, options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002368
2369 ch1.Stop();
2370 ch2.Stop();
2371}
2372
2373TEST_F(PortTest, TestTimeoutForNeverWritable) {
2374 UDPPort* port1 = CreateUdpPort(kLocalAddr1);
2375 UDPPort* port2 = CreateUdpPort(kLocalAddr2);
2376
2377 // Set up channels.
2378 TestChannel ch1(port1, port2);
2379 TestChannel ch2(port2, port1);
2380
2381 // Acquire addresses.
2382 ch1.Start();
2383 ch2.Start();
2384
2385 ch1.CreateConnection();
2386 ASSERT_TRUE(ch1.conn() != NULL);
2387 EXPECT_EQ(Connection::STATE_WRITE_INIT, ch1.conn()->write_state());
2388
2389 // Attempt to go directly to write timeout.
2390 for (uint32 i = 1; i <= CONNECTION_WRITE_CONNECT_FAILURES; ++i) {
2391 ch1.Ping(i);
2392 }
2393 ch1.conn()->UpdateState(CONNECTION_WRITE_TIMEOUT + 500u);
2394 EXPECT_EQ(Connection::STATE_WRITE_TIMEOUT, ch1.conn()->write_state());
2395}
2396
2397// This test verifies the connection setup between ICEMODE_FULL
2398// and ICEMODE_LITE.
2399// In this test |ch1| behaves like FULL mode client and we have created
2400// port which responds to the ping message just like LITE client.
2401TEST_F(PortTest, TestIceLiteConnectivity) {
2402 TestPort* ice_full_port = CreateTestPort(
2403 kLocalAddr1, "lfrag", "lpass", cricket::ICEPROTO_RFC5245,
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00002404 cricket::ICEROLE_CONTROLLING, kTiebreaker1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002405
2406 talk_base::scoped_ptr<TestPort> ice_lite_port(CreateTestPort(
2407 kLocalAddr2, "rfrag", "rpass", cricket::ICEPROTO_RFC5245,
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00002408 cricket::ICEROLE_CONTROLLED, kTiebreaker2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002409 // Setup TestChannel. This behaves like FULL mode client.
2410 TestChannel ch1(ice_full_port, ice_lite_port.get());
2411 ch1.SetIceMode(ICEMODE_FULL);
2412
2413 // Start gathering candidates.
2414 ch1.Start();
2415 ice_lite_port->PrepareAddress();
2416
2417 ASSERT_EQ_WAIT(1, ch1.complete_count(), kTimeout);
2418 ASSERT_FALSE(ice_lite_port->Candidates().empty());
2419
2420 ch1.CreateConnection();
2421 ASSERT_TRUE(ch1.conn() != NULL);
2422 EXPECT_EQ(Connection::STATE_WRITE_INIT, ch1.conn()->write_state());
2423
2424 // Send ping from full mode client.
2425 // This ping must not have USE_CANDIDATE_ATTR.
2426 ch1.Ping();
2427
2428 // Verify stun ping is without USE_CANDIDATE_ATTR. Getting message directly
2429 // from port.
2430 ASSERT_TRUE_WAIT(ice_full_port->last_stun_msg() != NULL, 1000);
2431 IceMessage* msg = ice_full_port->last_stun_msg();
2432 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) == NULL);
2433
2434 // Respond with a BINDING-RESPONSE from litemode client.
2435 // NOTE: Ideally we should't create connection at this stage from lite
2436 // port, as it should be done only after receiving ping with USE_CANDIDATE.
2437 // But we need a connection to send a response message.
2438 ice_lite_port->CreateConnection(
2439 ice_full_port->Candidates()[0], cricket::Port::ORIGIN_MESSAGE);
2440 talk_base::scoped_ptr<IceMessage> request(CopyStunMessage(msg));
2441 ice_lite_port->SendBindingResponse(
2442 request.get(), ice_full_port->Candidates()[0].address());
2443
2444 // Feeding the respone message from litemode to the full mode connection.
2445 ch1.conn()->OnReadPacket(ice_lite_port->last_stun_buf()->Data(),
wu@webrtc.orga9890802013-12-13 00:21:03 +00002446 ice_lite_port->last_stun_buf()->Length(),
2447 talk_base::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002448 // Verifying full mode connection becomes writable from the response.
2449 EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch1.conn()->write_state(),
2450 kTimeout);
2451 EXPECT_TRUE_WAIT(ch1.nominated(), kTimeout);
2452
2453 // Clear existing stun messsages. Otherwise we will process old stun
2454 // message right after we send ping.
2455 ice_full_port->Reset();
2456 // Send ping. This must have USE_CANDIDATE_ATTR.
2457 ch1.Ping();
2458 ASSERT_TRUE_WAIT(ice_full_port->last_stun_msg() != NULL, 1000);
2459 msg = ice_full_port->last_stun_msg();
2460 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) != NULL);
2461 ch1.Stop();
2462}
wu@webrtc.orgf6d6ed02014-01-03 22:08:47 +00002463
2464// This test case verifies that the CONTROLLING port does not time out.
2465TEST_F(PortTest, TestControllingNoTimeout) {
2466 SetIceProtocolType(cricket::ICEPROTO_RFC5245);
2467 UDPPort* port1 = CreateUdpPort(kLocalAddr1);
2468 ConnectToSignalDestroyed(port1);
2469 port1->set_timeout_delay(10); // milliseconds
2470 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
2471 port1->SetIceTiebreaker(kTiebreaker1);
2472
2473 UDPPort* port2 = CreateUdpPort(kLocalAddr2);
2474 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
2475 port2->SetIceTiebreaker(kTiebreaker2);
2476
2477 // Set up channels and ensure both ports will be deleted.
2478 TestChannel ch1(port1, port2);
2479 TestChannel ch2(port2, port1);
2480
2481 // Simulate a connection that succeeds, and then is destroyed.
2482 ConnectAndDisconnectChannels(&ch1, &ch2);
2483
2484 // After the connection is destroyed, the port should not be destroyed.
2485 talk_base::Thread::Current()->ProcessMessages(kTimeout);
2486 EXPECT_FALSE(destroyed());
2487}
2488
2489// This test case verifies that the CONTROLLED port does time out, but only
2490// after connectivity is lost.
2491TEST_F(PortTest, TestControlledTimeout) {
2492 SetIceProtocolType(cricket::ICEPROTO_RFC5245);
2493 UDPPort* port1 = CreateUdpPort(kLocalAddr1);
2494 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
2495 port1->SetIceTiebreaker(kTiebreaker1);
2496
2497 UDPPort* port2 = CreateUdpPort(kLocalAddr2);
2498 ConnectToSignalDestroyed(port2);
2499 port2->set_timeout_delay(10); // milliseconds
2500 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
2501 port2->SetIceTiebreaker(kTiebreaker2);
2502
2503 // The connection must not be destroyed before a connection is attempted.
2504 EXPECT_FALSE(destroyed());
2505
2506 port1->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
2507 port2->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
2508
2509 // Set up channels and ensure both ports will be deleted.
2510 TestChannel ch1(port1, port2);
2511 TestChannel ch2(port2, port1);
2512
2513 // Simulate a connection that succeeds, and then is destroyed.
2514 ConnectAndDisconnectChannels(&ch1, &ch2);
2515
2516 // The controlled port should be destroyed after 10 milliseconds.
2517 EXPECT_TRUE_WAIT(destroyed(), kTimeout);
2518}