blob: 61a2f4e558cfa4d96812ca40039eef087499db65 [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) {
473 TurnPort* port = TurnPort::Create(main_, socket_factory, &network_,
474 addr.ipaddr(), 0, 0,
475 username_, password_, ProtocolAddress(
476 kTurnUdpIntAddr, PROTO_UDP),
477 kRelayCredentials);
478 port->SetIceProtocolType(ice_protocol_);
479 return port;
480 }
481 RelayPort* CreateGturnPort(const SocketAddress& addr,
482 ProtocolType int_proto, ProtocolType ext_proto) {
483 RelayPort* port = CreateGturnPort(addr);
484 SocketAddress addrs[] =
485 { kRelayUdpIntAddr, kRelayTcpIntAddr, kRelaySslTcpIntAddr };
486 port->AddServerAddress(ProtocolAddress(addrs[int_proto], int_proto));
487 return port;
488 }
489 RelayPort* CreateGturnPort(const SocketAddress& addr) {
490 RelayPort* port = RelayPort::Create(main_, &socket_factory_, &network_,
491 addr.ipaddr(), 0, 0,
492 username_, password_);
493 // TODO: Add an external address for ext_proto, so that the
494 // other side can connect to this port using a non-UDP protocol.
495 port->SetIceProtocolType(ice_protocol_);
496 return port;
497 }
498 talk_base::NATServer* CreateNatServer(const SocketAddress& addr,
499 talk_base::NATType type) {
500 return new talk_base::NATServer(type, ss_.get(), addr, ss_.get(), addr);
501 }
502 static const char* StunName(NATType type) {
503 switch (type) {
504 case NAT_OPEN_CONE: return "stun(open cone)";
505 case NAT_ADDR_RESTRICTED: return "stun(addr restricted)";
506 case NAT_PORT_RESTRICTED: return "stun(port restricted)";
507 case NAT_SYMMETRIC: return "stun(symmetric)";
508 default: return "stun(?)";
509 }
510 }
511 static const char* RelayName(RelayType type, ProtocolType proto) {
512 if (type == RELAY_TURN) {
513 switch (proto) {
514 case PROTO_UDP: return "turn(udp)";
515 case PROTO_TCP: return "turn(tcp)";
516 case PROTO_SSLTCP: return "turn(ssltcp)";
517 default: return "turn(?)";
518 }
519 } else {
520 switch (proto) {
521 case PROTO_UDP: return "gturn(udp)";
522 case PROTO_TCP: return "gturn(tcp)";
523 case PROTO_SSLTCP: return "gturn(ssltcp)";
524 default: return "gturn(?)";
525 }
526 }
527 }
528
529 void TestCrossFamilyPorts(int type);
530
wu@webrtc.orgf6d6ed02014-01-03 22:08:47 +0000531 // This does all the work and then deletes |port1| and |port2|.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000532 void TestConnectivity(const char* name1, Port* port1,
533 const char* name2, Port* port2,
534 bool accept, bool same_addr1,
535 bool same_addr2, bool possible);
536
wu@webrtc.orgf6d6ed02014-01-03 22:08:47 +0000537 // This connects and disconnects the provided channels in the same sequence as
538 // TestConnectivity with all options set to |true|. It does not delete either
539 // channel.
540 void ConnectAndDisconnectChannels(TestChannel* ch1, TestChannel* ch2);
541
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000542 void SetIceProtocolType(cricket::IceProtocolType protocol) {
543 ice_protocol_ = protocol;
544 }
545
546 IceMessage* CreateStunMessage(int type) {
547 IceMessage* msg = new IceMessage();
548 msg->SetType(type);
549 msg->SetTransactionID("TESTTESTTEST");
550 return msg;
551 }
552 IceMessage* CreateStunMessageWithUsername(int type,
553 const std::string& username) {
554 IceMessage* msg = CreateStunMessage(type);
555 msg->AddAttribute(
556 new StunByteStringAttribute(STUN_ATTR_USERNAME, username));
557 return msg;
558 }
559 TestPort* CreateTestPort(const talk_base::SocketAddress& addr,
560 const std::string& username,
561 const std::string& password) {
562 TestPort* port = new TestPort(main_, "test", &socket_factory_, &network_,
563 addr.ipaddr(), 0, 0, username, password);
564 port->SignalRoleConflict.connect(this, &PortTest::OnRoleConflict);
565 return port;
566 }
567 TestPort* CreateTestPort(const talk_base::SocketAddress& addr,
568 const std::string& username,
569 const std::string& password,
570 cricket::IceProtocolType type,
mallinath@webrtc.orga5506692013-08-12 21:18:15 +0000571 cricket::IceRole role,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000572 int tiebreaker) {
573 TestPort* port = CreateTestPort(addr, username, password);
574 port->SetIceProtocolType(type);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +0000575 port->SetIceRole(role);
576 port->SetIceTiebreaker(tiebreaker);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000577 return port;
578 }
579
580 void OnRoleConflict(PortInterface* port) {
581 role_conflict_ = true;
582 }
583 bool role_conflict() const { return role_conflict_; }
584
wu@webrtc.orgf6d6ed02014-01-03 22:08:47 +0000585 void ConnectToSignalDestroyed(PortInterface* port) {
586 port->SignalDestroyed.connect(this, &PortTest::OnDestroyed);
587 }
588
589 void OnDestroyed(PortInterface* port) {
590 destroyed_ = true;
591 }
592 bool destroyed() const { return destroyed_; }
593
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000594 talk_base::BasicPacketSocketFactory* nat_socket_factory1() {
595 return &nat_socket_factory1_;
596 }
597
598 private:
599 talk_base::Thread* main_;
600 talk_base::scoped_ptr<talk_base::PhysicalSocketServer> pss_;
601 talk_base::scoped_ptr<talk_base::VirtualSocketServer> ss_;
602 talk_base::SocketServerScope ss_scope_;
603 talk_base::Network network_;
604 talk_base::BasicPacketSocketFactory socket_factory_;
605 talk_base::scoped_ptr<talk_base::NATServer> nat_server1_;
606 talk_base::scoped_ptr<talk_base::NATServer> nat_server2_;
607 talk_base::NATSocketFactory nat_factory1_;
608 talk_base::NATSocketFactory nat_factory2_;
609 talk_base::BasicPacketSocketFactory nat_socket_factory1_;
610 talk_base::BasicPacketSocketFactory nat_socket_factory2_;
611 TestStunServer stun_server_;
612 TestTurnServer turn_server_;
613 TestRelayServer relay_server_;
614 std::string username_;
615 std::string password_;
616 cricket::IceProtocolType ice_protocol_;
617 bool role_conflict_;
wu@webrtc.orgf6d6ed02014-01-03 22:08:47 +0000618 bool destroyed_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000619};
620
621void PortTest::TestConnectivity(const char* name1, Port* port1,
622 const char* name2, Port* port2,
623 bool accept, bool same_addr1,
624 bool same_addr2, bool possible) {
625 LOG(LS_INFO) << "Test: " << name1 << " to " << name2 << ": ";
626 port1->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
627 port2->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
628
wu@webrtc.orgf6d6ed02014-01-03 22:08:47 +0000629 // Set up channels and ensure both ports will be deleted.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000630 TestChannel ch1(port1, port2);
631 TestChannel ch2(port2, port1);
632 EXPECT_EQ(0, ch1.complete_count());
633 EXPECT_EQ(0, ch2.complete_count());
634
635 // Acquire addresses.
636 ch1.Start();
637 ch2.Start();
638 ASSERT_EQ_WAIT(1, ch1.complete_count(), kTimeout);
639 ASSERT_EQ_WAIT(1, ch2.complete_count(), kTimeout);
640
641 // Send a ping from src to dst. This may or may not make it.
642 ch1.CreateConnection();
643 ASSERT_TRUE(ch1.conn() != NULL);
644 EXPECT_TRUE_WAIT(ch1.conn()->connected(), kTimeout); // for TCP connect
645 ch1.Ping();
646 WAIT(!ch2.remote_address().IsNil(), kTimeout);
647
648 if (accept) {
649 // We are able to send a ping from src to dst. This is the case when
650 // sending to UDP ports and cone NATs.
651 EXPECT_TRUE(ch1.remote_address().IsNil());
652 EXPECT_EQ(ch2.remote_fragment(), port1->username_fragment());
653
654 // Ensure the ping came from the same address used for src.
655 // This is the case unless the source NAT was symmetric.
656 if (same_addr1) EXPECT_EQ(ch2.remote_address(), GetAddress(port1));
657 EXPECT_TRUE(same_addr2);
658
659 // Send a ping from dst to src.
660 ch2.AcceptConnection();
661 ASSERT_TRUE(ch2.conn() != NULL);
662 ch2.Ping();
663 EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch2.conn()->write_state(),
664 kTimeout);
665 } else {
666 // We can't send a ping from src to dst, so flip it around. This will happen
667 // when the destination NAT is addr/port restricted or symmetric.
668 EXPECT_TRUE(ch1.remote_address().IsNil());
669 EXPECT_TRUE(ch2.remote_address().IsNil());
670
671 // Send a ping from dst to src. Again, this may or may not make it.
672 ch2.CreateConnection();
673 ASSERT_TRUE(ch2.conn() != NULL);
674 ch2.Ping();
675 WAIT(ch2.conn()->write_state() == Connection::STATE_WRITABLE, kTimeout);
676
677 if (same_addr1 && same_addr2) {
678 // The new ping got back to the source.
679 EXPECT_EQ(Connection::STATE_READABLE, ch1.conn()->read_state());
680 EXPECT_EQ(Connection::STATE_WRITABLE, ch2.conn()->write_state());
681
682 // First connection may not be writable if the first ping did not get
683 // through. So we will have to do another.
684 if (ch1.conn()->write_state() == Connection::STATE_WRITE_INIT) {
685 ch1.Ping();
686 EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch1.conn()->write_state(),
687 kTimeout);
688 }
689 } else if (!same_addr1 && possible) {
690 // The new ping went to the candidate address, but that address was bad.
691 // This will happen when the source NAT is symmetric.
692 EXPECT_TRUE(ch1.remote_address().IsNil());
693 EXPECT_TRUE(ch2.remote_address().IsNil());
694
695 // However, since we have now sent a ping to the source IP, we should be
696 // able to get a ping from it. This gives us the real source address.
697 ch1.Ping();
698 EXPECT_TRUE_WAIT(!ch2.remote_address().IsNil(), kTimeout);
699 EXPECT_EQ(Connection::STATE_READ_INIT, ch2.conn()->read_state());
700 EXPECT_TRUE(ch1.remote_address().IsNil());
701
702 // Pick up the actual address and establish the connection.
703 ch2.AcceptConnection();
704 ASSERT_TRUE(ch2.conn() != NULL);
705 ch2.Ping();
706 EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch2.conn()->write_state(),
707 kTimeout);
708 } else if (!same_addr2 && possible) {
709 // The new ping came in, but from an unexpected address. This will happen
710 // when the destination NAT is symmetric.
711 EXPECT_FALSE(ch1.remote_address().IsNil());
712 EXPECT_EQ(Connection::STATE_READ_INIT, ch1.conn()->read_state());
713
714 // Update our address and complete the connection.
715 ch1.AcceptConnection();
716 ch1.Ping();
717 EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch1.conn()->write_state(),
718 kTimeout);
719 } else { // (!possible)
720 // There should be s no way for the pings to reach each other. Check it.
721 EXPECT_TRUE(ch1.remote_address().IsNil());
722 EXPECT_TRUE(ch2.remote_address().IsNil());
723 ch1.Ping();
724 WAIT(!ch2.remote_address().IsNil(), kTimeout);
725 EXPECT_TRUE(ch1.remote_address().IsNil());
726 EXPECT_TRUE(ch2.remote_address().IsNil());
727 }
728 }
729
730 // Everything should be good, unless we know the situation is impossible.
731 ASSERT_TRUE(ch1.conn() != NULL);
732 ASSERT_TRUE(ch2.conn() != NULL);
733 if (possible) {
734 EXPECT_EQ(Connection::STATE_READABLE, ch1.conn()->read_state());
735 EXPECT_EQ(Connection::STATE_WRITABLE, ch1.conn()->write_state());
736 EXPECT_EQ(Connection::STATE_READABLE, ch2.conn()->read_state());
737 EXPECT_EQ(Connection::STATE_WRITABLE, ch2.conn()->write_state());
738 } else {
739 EXPECT_NE(Connection::STATE_READABLE, ch1.conn()->read_state());
740 EXPECT_NE(Connection::STATE_WRITABLE, ch1.conn()->write_state());
741 EXPECT_NE(Connection::STATE_READABLE, ch2.conn()->read_state());
742 EXPECT_NE(Connection::STATE_WRITABLE, ch2.conn()->write_state());
743 }
744
745 // Tear down and ensure that goes smoothly.
746 ch1.Stop();
747 ch2.Stop();
748 EXPECT_TRUE_WAIT(ch1.conn() == NULL, kTimeout);
749 EXPECT_TRUE_WAIT(ch2.conn() == NULL, kTimeout);
750}
751
wu@webrtc.orgf6d6ed02014-01-03 22:08:47 +0000752void PortTest::ConnectAndDisconnectChannels(TestChannel* ch1,
753 TestChannel* ch2) {
754 // Acquire addresses.
755 ch1->Start();
756 ch2->Start();
757
758 // Send a ping from src to dst.
759 ch1->CreateConnection();
760 EXPECT_TRUE_WAIT(ch1->conn()->connected(), kTimeout); // for TCP connect
761 ch1->Ping();
762 WAIT(!ch2->remote_address().IsNil(), kTimeout);
763
764 // Send a ping from dst to src.
765 ch2->AcceptConnection();
766 ch2->Ping();
767 EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch2->conn()->write_state(),
768 kTimeout);
769
770 // Destroy the connections.
771 ch1->Stop();
772 ch2->Stop();
773}
774
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000775class FakePacketSocketFactory : public talk_base::PacketSocketFactory {
776 public:
777 FakePacketSocketFactory()
778 : next_udp_socket_(NULL),
779 next_server_tcp_socket_(NULL),
780 next_client_tcp_socket_(NULL) {
781 }
782 virtual ~FakePacketSocketFactory() { }
783
784 virtual AsyncPacketSocket* CreateUdpSocket(
785 const SocketAddress& address, int min_port, int max_port) {
786 EXPECT_TRUE(next_udp_socket_ != NULL);
787 AsyncPacketSocket* result = next_udp_socket_;
788 next_udp_socket_ = NULL;
789 return result;
790 }
791
792 virtual AsyncPacketSocket* CreateServerTcpSocket(
793 const SocketAddress& local_address, int min_port, int max_port,
794 int opts) {
795 EXPECT_TRUE(next_server_tcp_socket_ != NULL);
796 AsyncPacketSocket* result = next_server_tcp_socket_;
797 next_server_tcp_socket_ = NULL;
798 return result;
799 }
800
801 // TODO: |proxy_info| and |user_agent| should be set
802 // per-factory and not when socket is created.
803 virtual AsyncPacketSocket* CreateClientTcpSocket(
804 const SocketAddress& local_address, const SocketAddress& remote_address,
805 const talk_base::ProxyInfo& proxy_info,
806 const std::string& user_agent, int opts) {
807 EXPECT_TRUE(next_client_tcp_socket_ != NULL);
808 AsyncPacketSocket* result = next_client_tcp_socket_;
809 next_client_tcp_socket_ = NULL;
810 return result;
811 }
812
813 void set_next_udp_socket(AsyncPacketSocket* next_udp_socket) {
814 next_udp_socket_ = next_udp_socket;
815 }
816 void set_next_server_tcp_socket(AsyncPacketSocket* next_server_tcp_socket) {
817 next_server_tcp_socket_ = next_server_tcp_socket;
818 }
819 void set_next_client_tcp_socket(AsyncPacketSocket* next_client_tcp_socket) {
820 next_client_tcp_socket_ = next_client_tcp_socket;
821 }
sergeyu@chromium.orga23f0ca2013-11-13 22:48:52 +0000822 talk_base::AsyncResolverInterface* CreateAsyncResolver() {
823 return NULL;
824 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000825
826 private:
827 AsyncPacketSocket* next_udp_socket_;
828 AsyncPacketSocket* next_server_tcp_socket_;
829 AsyncPacketSocket* next_client_tcp_socket_;
830};
831
832class FakeAsyncPacketSocket : public AsyncPacketSocket {
833 public:
834 // Returns current local address. Address may be set to NULL if the
835 // socket is not bound yet (GetState() returns STATE_BINDING).
836 virtual SocketAddress GetLocalAddress() const {
837 return SocketAddress();
838 }
839
840 // Returns remote address. Returns zeroes if this is not a client TCP socket.
841 virtual SocketAddress GetRemoteAddress() const {
842 return SocketAddress();
843 }
844
845 // Send a packet.
mallinath@webrtc.org1112c302013-09-23 20:34:45 +0000846 virtual int Send(const void *pv, size_t cb,
mallinath@webrtc.org385857d2014-02-14 00:56:12 +0000847 const talk_base::PacketOptions& options) {
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000848 return static_cast<int>(cb);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000849 }
mallinath@webrtc.org1112c302013-09-23 20:34:45 +0000850 virtual int SendTo(const void *pv, size_t cb, const SocketAddress& addr,
mallinath@webrtc.org385857d2014-02-14 00:56:12 +0000851 const talk_base::PacketOptions& options) {
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000852 return static_cast<int>(cb);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000853 }
854 virtual int Close() {
855 return 0;
856 }
857
858 virtual State GetState() const { return state_; }
859 virtual int GetOption(Socket::Option opt, int* value) { return 0; }
860 virtual int SetOption(Socket::Option opt, int value) { return 0; }
861 virtual int GetError() const { return 0; }
862 virtual void SetError(int error) { }
863
864 void set_state(State state) { state_ = state; }
865
866 private:
867 State state_;
868};
869
870// Local -> XXXX
871TEST_F(PortTest, TestLocalToLocal) {
872 TestLocalToLocal();
873}
874
875TEST_F(PortTest, TestLocalToConeNat) {
876 TestLocalToStun(NAT_OPEN_CONE);
877}
878
879TEST_F(PortTest, TestLocalToARNat) {
880 TestLocalToStun(NAT_ADDR_RESTRICTED);
881}
882
883TEST_F(PortTest, TestLocalToPRNat) {
884 TestLocalToStun(NAT_PORT_RESTRICTED);
885}
886
887TEST_F(PortTest, TestLocalToSymNat) {
888 TestLocalToStun(NAT_SYMMETRIC);
889}
890
891TEST_F(PortTest, TestLocalToTurn) {
892 TestLocalToRelay(RELAY_TURN, PROTO_UDP);
893}
894
895TEST_F(PortTest, TestLocalToGturn) {
896 TestLocalToRelay(RELAY_GTURN, PROTO_UDP);
897}
898
899TEST_F(PortTest, TestLocalToTcpGturn) {
900 TestLocalToRelay(RELAY_GTURN, PROTO_TCP);
901}
902
903TEST_F(PortTest, TestLocalToSslTcpGturn) {
904 TestLocalToRelay(RELAY_GTURN, PROTO_SSLTCP);
905}
906
907// Cone NAT -> XXXX
908TEST_F(PortTest, TestConeNatToLocal) {
909 TestStunToLocal(NAT_OPEN_CONE);
910}
911
912TEST_F(PortTest, TestConeNatToConeNat) {
913 TestStunToStun(NAT_OPEN_CONE, NAT_OPEN_CONE);
914}
915
916TEST_F(PortTest, TestConeNatToARNat) {
917 TestStunToStun(NAT_OPEN_CONE, NAT_ADDR_RESTRICTED);
918}
919
920TEST_F(PortTest, TestConeNatToPRNat) {
921 TestStunToStun(NAT_OPEN_CONE, NAT_PORT_RESTRICTED);
922}
923
924TEST_F(PortTest, TestConeNatToSymNat) {
925 TestStunToStun(NAT_OPEN_CONE, NAT_SYMMETRIC);
926}
927
928TEST_F(PortTest, TestConeNatToTurn) {
929 TestStunToRelay(NAT_OPEN_CONE, RELAY_TURN, PROTO_UDP);
930}
931
932TEST_F(PortTest, TestConeNatToGturn) {
933 TestStunToRelay(NAT_OPEN_CONE, RELAY_GTURN, PROTO_UDP);
934}
935
936TEST_F(PortTest, TestConeNatToTcpGturn) {
937 TestStunToRelay(NAT_OPEN_CONE, RELAY_GTURN, PROTO_TCP);
938}
939
940// Address-restricted NAT -> XXXX
941TEST_F(PortTest, TestARNatToLocal) {
942 TestStunToLocal(NAT_ADDR_RESTRICTED);
943}
944
945TEST_F(PortTest, TestARNatToConeNat) {
946 TestStunToStun(NAT_ADDR_RESTRICTED, NAT_OPEN_CONE);
947}
948
949TEST_F(PortTest, TestARNatToARNat) {
950 TestStunToStun(NAT_ADDR_RESTRICTED, NAT_ADDR_RESTRICTED);
951}
952
953TEST_F(PortTest, TestARNatToPRNat) {
954 TestStunToStun(NAT_ADDR_RESTRICTED, NAT_PORT_RESTRICTED);
955}
956
957TEST_F(PortTest, TestARNatToSymNat) {
958 TestStunToStun(NAT_ADDR_RESTRICTED, NAT_SYMMETRIC);
959}
960
961TEST_F(PortTest, TestARNatToTurn) {
962 TestStunToRelay(NAT_ADDR_RESTRICTED, RELAY_TURN, PROTO_UDP);
963}
964
965TEST_F(PortTest, TestARNatToGturn) {
966 TestStunToRelay(NAT_ADDR_RESTRICTED, RELAY_GTURN, PROTO_UDP);
967}
968
969TEST_F(PortTest, TestARNATNatToTcpGturn) {
970 TestStunToRelay(NAT_ADDR_RESTRICTED, RELAY_GTURN, PROTO_TCP);
971}
972
973// Port-restricted NAT -> XXXX
974TEST_F(PortTest, TestPRNatToLocal) {
975 TestStunToLocal(NAT_PORT_RESTRICTED);
976}
977
978TEST_F(PortTest, TestPRNatToConeNat) {
979 TestStunToStun(NAT_PORT_RESTRICTED, NAT_OPEN_CONE);
980}
981
982TEST_F(PortTest, TestPRNatToARNat) {
983 TestStunToStun(NAT_PORT_RESTRICTED, NAT_ADDR_RESTRICTED);
984}
985
986TEST_F(PortTest, TestPRNatToPRNat) {
987 TestStunToStun(NAT_PORT_RESTRICTED, NAT_PORT_RESTRICTED);
988}
989
990TEST_F(PortTest, TestPRNatToSymNat) {
991 // Will "fail"
992 TestStunToStun(NAT_PORT_RESTRICTED, NAT_SYMMETRIC);
993}
994
995TEST_F(PortTest, TestPRNatToTurn) {
996 TestStunToRelay(NAT_PORT_RESTRICTED, RELAY_TURN, PROTO_UDP);
997}
998
999TEST_F(PortTest, TestPRNatToGturn) {
1000 TestStunToRelay(NAT_PORT_RESTRICTED, RELAY_GTURN, PROTO_UDP);
1001}
1002
1003TEST_F(PortTest, TestPRNatToTcpGturn) {
1004 TestStunToRelay(NAT_PORT_RESTRICTED, RELAY_GTURN, PROTO_TCP);
1005}
1006
1007// Symmetric NAT -> XXXX
1008TEST_F(PortTest, TestSymNatToLocal) {
1009 TestStunToLocal(NAT_SYMMETRIC);
1010}
1011
1012TEST_F(PortTest, TestSymNatToConeNat) {
1013 TestStunToStun(NAT_SYMMETRIC, NAT_OPEN_CONE);
1014}
1015
1016TEST_F(PortTest, TestSymNatToARNat) {
1017 TestStunToStun(NAT_SYMMETRIC, NAT_ADDR_RESTRICTED);
1018}
1019
1020TEST_F(PortTest, TestSymNatToPRNat) {
1021 // Will "fail"
1022 TestStunToStun(NAT_SYMMETRIC, NAT_PORT_RESTRICTED);
1023}
1024
1025TEST_F(PortTest, TestSymNatToSymNat) {
1026 // Will "fail"
1027 TestStunToStun(NAT_SYMMETRIC, NAT_SYMMETRIC);
1028}
1029
1030TEST_F(PortTest, TestSymNatToTurn) {
1031 TestStunToRelay(NAT_SYMMETRIC, RELAY_TURN, PROTO_UDP);
1032}
1033
1034TEST_F(PortTest, TestSymNatToGturn) {
1035 TestStunToRelay(NAT_SYMMETRIC, RELAY_GTURN, PROTO_UDP);
1036}
1037
1038TEST_F(PortTest, TestSymNatToTcpGturn) {
1039 TestStunToRelay(NAT_SYMMETRIC, RELAY_GTURN, PROTO_TCP);
1040}
1041
1042// Outbound TCP -> XXXX
1043TEST_F(PortTest, TestTcpToTcp) {
1044 TestTcpToTcp();
1045}
1046
1047/* TODO: Enable these once testrelayserver can accept external TCP.
1048TEST_F(PortTest, TestTcpToTcpRelay) {
1049 TestTcpToRelay(PROTO_TCP);
1050}
1051
1052TEST_F(PortTest, TestTcpToSslTcpRelay) {
1053 TestTcpToRelay(PROTO_SSLTCP);
1054}
1055*/
1056
1057// Outbound SSLTCP -> XXXX
1058/* TODO: Enable these once testrelayserver can accept external SSL.
1059TEST_F(PortTest, TestSslTcpToTcpRelay) {
1060 TestSslTcpToRelay(PROTO_TCP);
1061}
1062
1063TEST_F(PortTest, TestSslTcpToSslTcpRelay) {
1064 TestSslTcpToRelay(PROTO_SSLTCP);
1065}
1066*/
1067
1068// This test case verifies standard ICE features in STUN messages. Currently it
1069// verifies Message Integrity attribute in STUN messages and username in STUN
1070// binding request will have colon (":") between remote and local username.
1071TEST_F(PortTest, TestLocalToLocalAsIce) {
1072 SetIceProtocolType(cricket::ICEPROTO_RFC5245);
1073 UDPPort* port1 = CreateUdpPort(kLocalAddr1);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00001074 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
1075 port1->SetIceTiebreaker(kTiebreaker1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001076 ASSERT_EQ(cricket::ICEPROTO_RFC5245, port1->IceProtocol());
1077 UDPPort* port2 = CreateUdpPort(kLocalAddr2);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00001078 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
1079 port2->SetIceTiebreaker(kTiebreaker2);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001080 ASSERT_EQ(cricket::ICEPROTO_RFC5245, port2->IceProtocol());
1081 // Same parameters as TestLocalToLocal above.
1082 TestConnectivity("udp", port1, "udp", port2, true, true, true, true);
1083}
1084
1085// This test is trying to validate a successful and failure scenario in a
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00001086// loopback test when protocol is RFC5245. For success IceTiebreaker, username
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001087// should remain equal to the request generated by the port and role of port
1088// must be in controlling.
1089TEST_F(PortTest, TestLoopbackCallAsIce) {
1090 talk_base::scoped_ptr<TestPort> lport(
1091 CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
1092 lport->SetIceProtocolType(ICEPROTO_RFC5245);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00001093 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1094 lport->SetIceTiebreaker(kTiebreaker1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001095 lport->PrepareAddress();
1096 ASSERT_FALSE(lport->Candidates().empty());
1097 Connection* conn = lport->CreateConnection(lport->Candidates()[0],
1098 Port::ORIGIN_MESSAGE);
1099 conn->Ping(0);
1100
1101 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, 1000);
1102 IceMessage* msg = lport->last_stun_msg();
1103 EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
1104 conn->OnReadPacket(lport->last_stun_buf()->Data(),
wu@webrtc.orga9890802013-12-13 00:21:03 +00001105 lport->last_stun_buf()->Length(),
1106 talk_base::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001107 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, 1000);
1108 msg = lport->last_stun_msg();
1109 EXPECT_EQ(STUN_BINDING_RESPONSE, msg->type());
1110
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00001111 // If the tiebreaker value is different from port, we expect a error
1112 // response.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001113 lport->Reset();
1114 lport->AddCandidateAddress(kLocalAddr2);
1115 // Creating a different connection as |conn| is in STATE_READABLE.
1116 Connection* conn1 = lport->CreateConnection(lport->Candidates()[1],
1117 Port::ORIGIN_MESSAGE);
1118 conn1->Ping(0);
1119
1120 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, 1000);
1121 msg = lport->last_stun_msg();
1122 EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001123 talk_base::scoped_ptr<IceMessage> modified_req(
1124 CreateStunMessage(STUN_BINDING_REQUEST));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001125 const StunByteStringAttribute* username_attr = msg->GetByteString(
1126 STUN_ATTR_USERNAME);
1127 modified_req->AddAttribute(new StunByteStringAttribute(
1128 STUN_ATTR_USERNAME, username_attr->GetString()));
1129 // To make sure we receive error response, adding tiebreaker less than
1130 // what's present in request.
1131 modified_req->AddAttribute(new StunUInt64Attribute(
1132 STUN_ATTR_ICE_CONTROLLING, kTiebreaker1 - 1));
1133 modified_req->AddMessageIntegrity("lpass");
1134 modified_req->AddFingerprint();
1135
1136 lport->Reset();
1137 talk_base::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00001138 WriteStunMessage(modified_req.get(), buf.get());
wu@webrtc.orga9890802013-12-13 00:21:03 +00001139 conn1->OnReadPacket(buf->Data(), buf->Length(), talk_base::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001140 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, 1000);
1141 msg = lport->last_stun_msg();
1142 EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, msg->type());
1143}
1144
1145// This test verifies role conflict signal is received when there is
1146// conflict in the role. In this case both ports are in controlling and
1147// |rport| has higher tiebreaker value than |lport|. Since |lport| has lower
1148// value of tiebreaker, when it receives ping request from |rport| it will
1149// send role conflict signal.
1150TEST_F(PortTest, TestIceRoleConflict) {
1151 talk_base::scoped_ptr<TestPort> lport(
1152 CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
1153 lport->SetIceProtocolType(ICEPROTO_RFC5245);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00001154 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1155 lport->SetIceTiebreaker(kTiebreaker1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001156 talk_base::scoped_ptr<TestPort> rport(
1157 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1158 rport->SetIceProtocolType(ICEPROTO_RFC5245);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00001159 rport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1160 rport->SetIceTiebreaker(kTiebreaker2);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001161
1162 lport->PrepareAddress();
1163 rport->PrepareAddress();
1164 ASSERT_FALSE(lport->Candidates().empty());
1165 ASSERT_FALSE(rport->Candidates().empty());
1166 Connection* lconn = lport->CreateConnection(rport->Candidates()[0],
1167 Port::ORIGIN_MESSAGE);
1168 Connection* rconn = rport->CreateConnection(lport->Candidates()[0],
1169 Port::ORIGIN_MESSAGE);
1170 rconn->Ping(0);
1171
1172 ASSERT_TRUE_WAIT(rport->last_stun_msg() != NULL, 1000);
1173 IceMessage* msg = rport->last_stun_msg();
1174 EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
1175 // Send rport binding request to lport.
1176 lconn->OnReadPacket(rport->last_stun_buf()->Data(),
wu@webrtc.orga9890802013-12-13 00:21:03 +00001177 rport->last_stun_buf()->Length(),
1178 talk_base::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001179
1180 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, 1000);
1181 EXPECT_EQ(STUN_BINDING_RESPONSE, lport->last_stun_msg()->type());
1182 EXPECT_TRUE(role_conflict());
1183}
1184
1185TEST_F(PortTest, TestTcpNoDelay) {
1186 TCPPort* port1 = CreateTcpPort(kLocalAddr1);
1187 int option_value = -1;
1188 int success = port1->GetOption(talk_base::Socket::OPT_NODELAY,
1189 &option_value);
1190 ASSERT_EQ(0, success); // GetOption() should complete successfully w/ 0
1191 ASSERT_EQ(1, option_value);
1192 delete port1;
1193}
1194
1195TEST_F(PortTest, TestDelayedBindingUdp) {
1196 FakeAsyncPacketSocket *socket = new FakeAsyncPacketSocket();
1197 FakePacketSocketFactory socket_factory;
1198
1199 socket_factory.set_next_udp_socket(socket);
1200 scoped_ptr<UDPPort> port(
1201 CreateUdpPort(kLocalAddr1, &socket_factory));
1202
1203 socket->set_state(AsyncPacketSocket::STATE_BINDING);
1204 port->PrepareAddress();
1205
1206 EXPECT_EQ(0U, port->Candidates().size());
1207 socket->SignalAddressReady(socket, kLocalAddr2);
1208
1209 EXPECT_EQ(1U, port->Candidates().size());
1210}
1211
1212TEST_F(PortTest, TestDelayedBindingTcp) {
1213 FakeAsyncPacketSocket *socket = new FakeAsyncPacketSocket();
1214 FakePacketSocketFactory socket_factory;
1215
1216 socket_factory.set_next_server_tcp_socket(socket);
1217 scoped_ptr<TCPPort> port(
1218 CreateTcpPort(kLocalAddr1, &socket_factory));
1219
1220 socket->set_state(AsyncPacketSocket::STATE_BINDING);
1221 port->PrepareAddress();
1222
1223 EXPECT_EQ(0U, port->Candidates().size());
1224 socket->SignalAddressReady(socket, kLocalAddr2);
1225
1226 EXPECT_EQ(1U, port->Candidates().size());
1227}
1228
1229void PortTest::TestCrossFamilyPorts(int type) {
1230 FakePacketSocketFactory factory;
1231 scoped_ptr<Port> ports[4];
1232 SocketAddress addresses[4] = {SocketAddress("192.168.1.3", 0),
1233 SocketAddress("192.168.1.4", 0),
1234 SocketAddress("2001:db8::1", 0),
1235 SocketAddress("2001:db8::2", 0)};
1236 for (int i = 0; i < 4; i++) {
1237 FakeAsyncPacketSocket *socket = new FakeAsyncPacketSocket();
1238 if (type == SOCK_DGRAM) {
1239 factory.set_next_udp_socket(socket);
1240 ports[i].reset(CreateUdpPort(addresses[i], &factory));
1241 } else if (type == SOCK_STREAM) {
1242 factory.set_next_server_tcp_socket(socket);
1243 ports[i].reset(CreateTcpPort(addresses[i], &factory));
1244 }
1245 socket->set_state(AsyncPacketSocket::STATE_BINDING);
1246 socket->SignalAddressReady(socket, addresses[i]);
1247 ports[i]->PrepareAddress();
1248 }
1249
1250 // IPv4 Port, connects to IPv6 candidate and then to IPv4 candidate.
1251 if (type == SOCK_STREAM) {
1252 FakeAsyncPacketSocket* clientsocket = new FakeAsyncPacketSocket();
1253 factory.set_next_client_tcp_socket(clientsocket);
1254 }
1255 Connection* c = ports[0]->CreateConnection(GetCandidate(ports[2].get()),
1256 Port::ORIGIN_MESSAGE);
1257 EXPECT_TRUE(NULL == c);
1258 EXPECT_EQ(0U, ports[0]->connections().size());
1259 c = ports[0]->CreateConnection(GetCandidate(ports[1].get()),
1260 Port::ORIGIN_MESSAGE);
1261 EXPECT_FALSE(NULL == c);
1262 EXPECT_EQ(1U, ports[0]->connections().size());
1263
1264 // IPv6 Port, connects to IPv4 candidate and to IPv6 candidate.
1265 if (type == SOCK_STREAM) {
1266 FakeAsyncPacketSocket* clientsocket = new FakeAsyncPacketSocket();
1267 factory.set_next_client_tcp_socket(clientsocket);
1268 }
1269 c = ports[2]->CreateConnection(GetCandidate(ports[0].get()),
1270 Port::ORIGIN_MESSAGE);
1271 EXPECT_TRUE(NULL == c);
1272 EXPECT_EQ(0U, ports[2]->connections().size());
1273 c = ports[2]->CreateConnection(GetCandidate(ports[3].get()),
1274 Port::ORIGIN_MESSAGE);
1275 EXPECT_FALSE(NULL == c);
1276 EXPECT_EQ(1U, ports[2]->connections().size());
1277}
1278
1279TEST_F(PortTest, TestSkipCrossFamilyTcp) {
1280 TestCrossFamilyPorts(SOCK_STREAM);
1281}
1282
1283TEST_F(PortTest, TestSkipCrossFamilyUdp) {
1284 TestCrossFamilyPorts(SOCK_DGRAM);
1285}
1286
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00001287// This test verifies DSCP value set through SetOption interface can be
1288// get through DefaultDscpValue.
1289TEST_F(PortTest, TestDefaultDscpValue) {
mallinath@webrtc.org67ee6b92014-02-03 16:57:16 +00001290 int dscp;
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00001291 talk_base::scoped_ptr<UDPPort> udpport(CreateUdpPort(kLocalAddr1));
mallinath@webrtc.org67ee6b92014-02-03 16:57:16 +00001292 EXPECT_EQ(0, udpport->SetOption(talk_base::Socket::OPT_DSCP,
1293 talk_base::DSCP_CS6));
1294 EXPECT_EQ(0, udpport->GetOption(talk_base::Socket::OPT_DSCP, &dscp));
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00001295 talk_base::scoped_ptr<TCPPort> tcpport(CreateTcpPort(kLocalAddr1));
mallinath@webrtc.org67ee6b92014-02-03 16:57:16 +00001296 EXPECT_EQ(0, tcpport->SetOption(talk_base::Socket::OPT_DSCP,
1297 talk_base::DSCP_AF31));
1298 EXPECT_EQ(0, tcpport->GetOption(talk_base::Socket::OPT_DSCP, &dscp));
1299 EXPECT_EQ(talk_base::DSCP_AF31, dscp);
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00001300 talk_base::scoped_ptr<StunPort> stunport(
1301 CreateStunPort(kLocalAddr1, nat_socket_factory1()));
mallinath@webrtc.org67ee6b92014-02-03 16:57:16 +00001302 EXPECT_EQ(0, stunport->SetOption(talk_base::Socket::OPT_DSCP,
1303 talk_base::DSCP_AF41));
1304 EXPECT_EQ(0, stunport->GetOption(talk_base::Socket::OPT_DSCP, &dscp));
1305 EXPECT_EQ(talk_base::DSCP_AF41, dscp);
1306 talk_base::scoped_ptr<TurnPort> turnport1(CreateTurnPort(
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00001307 kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
mallinath@webrtc.org67ee6b92014-02-03 16:57:16 +00001308 // Socket is created in PrepareAddress.
1309 turnport1->PrepareAddress();
1310 EXPECT_EQ(0, turnport1->SetOption(talk_base::Socket::OPT_DSCP,
1311 talk_base::DSCP_CS7));
1312 EXPECT_EQ(0, turnport1->GetOption(talk_base::Socket::OPT_DSCP, &dscp));
1313 EXPECT_EQ(talk_base::DSCP_CS7, dscp);
1314 // This will verify correct value returned without the socket.
1315 talk_base::scoped_ptr<TurnPort> turnport2(CreateTurnPort(
1316 kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
1317 EXPECT_EQ(0, turnport2->SetOption(talk_base::Socket::OPT_DSCP,
1318 talk_base::DSCP_CS6));
1319 EXPECT_EQ(0, turnport2->GetOption(talk_base::Socket::OPT_DSCP, &dscp));
1320 EXPECT_EQ(talk_base::DSCP_CS6, dscp);
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00001321}
1322
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001323// Test sending STUN messages in GICE format.
1324TEST_F(PortTest, TestSendStunMessageAsGice) {
1325 talk_base::scoped_ptr<TestPort> lport(
1326 CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
1327 talk_base::scoped_ptr<TestPort> rport(
1328 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1329 lport->SetIceProtocolType(ICEPROTO_GOOGLE);
1330 rport->SetIceProtocolType(ICEPROTO_GOOGLE);
1331
1332 // Send a fake ping from lport to rport.
1333 lport->PrepareAddress();
1334 rport->PrepareAddress();
1335 ASSERT_FALSE(rport->Candidates().empty());
1336 Connection* conn = lport->CreateConnection(rport->Candidates()[0],
1337 Port::ORIGIN_MESSAGE);
1338 rport->CreateConnection(lport->Candidates()[0], Port::ORIGIN_MESSAGE);
1339 conn->Ping(0);
1340
1341 // Check that it's a proper BINDING-REQUEST.
1342 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, 1000);
1343 IceMessage* msg = lport->last_stun_msg();
1344 EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
1345 EXPECT_FALSE(msg->IsLegacy());
1346 const StunByteStringAttribute* username_attr = msg->GetByteString(
1347 STUN_ATTR_USERNAME);
1348 ASSERT_TRUE(username_attr != NULL);
1349 EXPECT_EQ("rfraglfrag", username_attr->GetString());
1350 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) == NULL);
1351 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_PRIORITY) == NULL);
1352 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_FINGERPRINT) == NULL);
1353
1354 // Save a copy of the BINDING-REQUEST for use below.
1355 talk_base::scoped_ptr<IceMessage> request(CopyStunMessage(msg));
1356
1357 // Respond with a BINDING-RESPONSE.
1358 rport->SendBindingResponse(request.get(), lport->Candidates()[0].address());
1359 msg = rport->last_stun_msg();
1360 ASSERT_TRUE(msg != NULL);
1361 EXPECT_EQ(STUN_BINDING_RESPONSE, msg->type());
1362 EXPECT_FALSE(msg->IsLegacy());
1363 username_attr = msg->GetByteString(STUN_ATTR_USERNAME);
1364 ASSERT_TRUE(username_attr != NULL); // GICE has a username in the response.
1365 EXPECT_EQ("rfraglfrag", username_attr->GetString());
1366 const StunAddressAttribute* addr_attr = msg->GetAddress(
1367 STUN_ATTR_MAPPED_ADDRESS);
1368 ASSERT_TRUE(addr_attr != NULL);
1369 EXPECT_EQ(lport->Candidates()[0].address(), addr_attr->GetAddress());
1370 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_XOR_MAPPED_ADDRESS) == NULL);
1371 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) == NULL);
1372 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_PRIORITY) == NULL);
1373 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_FINGERPRINT) == NULL);
1374
1375 // Respond with a BINDING-ERROR-RESPONSE. This wouldn't happen in real life,
1376 // but we can do it here.
1377 rport->SendBindingErrorResponse(request.get(),
1378 rport->Candidates()[0].address(),
1379 STUN_ERROR_SERVER_ERROR,
1380 STUN_ERROR_REASON_SERVER_ERROR);
1381 msg = rport->last_stun_msg();
1382 ASSERT_TRUE(msg != NULL);
1383 EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, msg->type());
1384 EXPECT_FALSE(msg->IsLegacy());
1385 username_attr = msg->GetByteString(STUN_ATTR_USERNAME);
1386 ASSERT_TRUE(username_attr != NULL); // GICE has a username in the response.
1387 EXPECT_EQ("rfraglfrag", username_attr->GetString());
1388 const StunErrorCodeAttribute* error_attr = msg->GetErrorCode();
1389 ASSERT_TRUE(error_attr != NULL);
1390 // The GICE wire format for error codes is incorrect.
1391 EXPECT_EQ(STUN_ERROR_SERVER_ERROR_AS_GICE, error_attr->code());
1392 EXPECT_EQ(STUN_ERROR_SERVER_ERROR / 256, error_attr->eclass());
1393 EXPECT_EQ(STUN_ERROR_SERVER_ERROR % 256, error_attr->number());
1394 EXPECT_EQ(std::string(STUN_ERROR_REASON_SERVER_ERROR), error_attr->reason());
1395 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_PRIORITY) == NULL);
1396 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) == NULL);
1397 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_FINGERPRINT) == NULL);
1398}
1399
1400// Test sending STUN messages in ICE format.
1401TEST_F(PortTest, TestSendStunMessageAsIce) {
1402 talk_base::scoped_ptr<TestPort> lport(
1403 CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
1404 talk_base::scoped_ptr<TestPort> rport(
1405 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1406 lport->SetIceProtocolType(ICEPROTO_RFC5245);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00001407 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1408 lport->SetIceTiebreaker(kTiebreaker1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001409 rport->SetIceProtocolType(ICEPROTO_RFC5245);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00001410 rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
1411 rport->SetIceTiebreaker(kTiebreaker2);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001412
1413 // Send a fake ping from lport to rport.
1414 lport->PrepareAddress();
1415 rport->PrepareAddress();
1416 ASSERT_FALSE(rport->Candidates().empty());
1417 Connection* lconn = lport->CreateConnection(
1418 rport->Candidates()[0], Port::ORIGIN_MESSAGE);
1419 Connection* rconn = rport->CreateConnection(
1420 lport->Candidates()[0], Port::ORIGIN_MESSAGE);
1421 lconn->Ping(0);
1422
1423 // Check that it's a proper BINDING-REQUEST.
1424 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, 1000);
1425 IceMessage* msg = lport->last_stun_msg();
1426 EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
1427 EXPECT_FALSE(msg->IsLegacy());
1428 const StunByteStringAttribute* username_attr =
1429 msg->GetByteString(STUN_ATTR_USERNAME);
1430 ASSERT_TRUE(username_attr != NULL);
1431 const StunUInt32Attribute* priority_attr = msg->GetUInt32(STUN_ATTR_PRIORITY);
1432 ASSERT_TRUE(priority_attr != NULL);
1433 EXPECT_EQ(kDefaultPrflxPriority, priority_attr->value());
1434 EXPECT_EQ("rfrag:lfrag", username_attr->GetString());
1435 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL);
1436 EXPECT_TRUE(StunMessage::ValidateMessageIntegrity(
1437 lport->last_stun_buf()->Data(), lport->last_stun_buf()->Length(),
1438 "rpass"));
1439 const StunUInt64Attribute* ice_controlling_attr =
1440 msg->GetUInt64(STUN_ATTR_ICE_CONTROLLING);
1441 ASSERT_TRUE(ice_controlling_attr != NULL);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00001442 EXPECT_EQ(lport->IceTiebreaker(), ice_controlling_attr->value());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001443 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_ICE_CONTROLLED) == NULL);
1444 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) != NULL);
1445 EXPECT_TRUE(msg->GetUInt32(STUN_ATTR_FINGERPRINT) != NULL);
1446 EXPECT_TRUE(StunMessage::ValidateFingerprint(
1447 lport->last_stun_buf()->Data(), lport->last_stun_buf()->Length()));
1448
1449 // Request should not include ping count.
1450 ASSERT_TRUE(msg->GetUInt32(STUN_ATTR_RETRANSMIT_COUNT) == NULL);
1451
1452 // Save a copy of the BINDING-REQUEST for use below.
1453 talk_base::scoped_ptr<IceMessage> request(CopyStunMessage(msg));
1454
1455 // Respond with a BINDING-RESPONSE.
1456 rport->SendBindingResponse(request.get(), lport->Candidates()[0].address());
1457 msg = rport->last_stun_msg();
1458 ASSERT_TRUE(msg != NULL);
1459 EXPECT_EQ(STUN_BINDING_RESPONSE, msg->type());
1460
1461
1462 EXPECT_FALSE(msg->IsLegacy());
1463 const StunAddressAttribute* addr_attr = msg->GetAddress(
1464 STUN_ATTR_XOR_MAPPED_ADDRESS);
1465 ASSERT_TRUE(addr_attr != NULL);
1466 EXPECT_EQ(lport->Candidates()[0].address(), addr_attr->GetAddress());
1467 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL);
1468 EXPECT_TRUE(StunMessage::ValidateMessageIntegrity(
1469 rport->last_stun_buf()->Data(), rport->last_stun_buf()->Length(),
1470 "rpass"));
1471 EXPECT_TRUE(msg->GetUInt32(STUN_ATTR_FINGERPRINT) != NULL);
1472 EXPECT_TRUE(StunMessage::ValidateFingerprint(
1473 lport->last_stun_buf()->Data(), lport->last_stun_buf()->Length()));
1474 // No USERNAME or PRIORITY in ICE responses.
1475 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USERNAME) == NULL);
1476 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_PRIORITY) == NULL);
1477 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MAPPED_ADDRESS) == NULL);
1478 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_ICE_CONTROLLING) == NULL);
1479 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_ICE_CONTROLLED) == NULL);
1480 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) == NULL);
1481
1482 // Response should not include ping count.
1483 ASSERT_TRUE(msg->GetUInt32(STUN_ATTR_RETRANSMIT_COUNT) == NULL);
1484
1485 // Respond with a BINDING-ERROR-RESPONSE. This wouldn't happen in real life,
1486 // but we can do it here.
1487 rport->SendBindingErrorResponse(request.get(),
1488 lport->Candidates()[0].address(),
1489 STUN_ERROR_SERVER_ERROR,
1490 STUN_ERROR_REASON_SERVER_ERROR);
1491 msg = rport->last_stun_msg();
1492 ASSERT_TRUE(msg != NULL);
1493 EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, msg->type());
1494 EXPECT_FALSE(msg->IsLegacy());
1495 const StunErrorCodeAttribute* error_attr = msg->GetErrorCode();
1496 ASSERT_TRUE(error_attr != NULL);
1497 EXPECT_EQ(STUN_ERROR_SERVER_ERROR, error_attr->code());
1498 EXPECT_EQ(std::string(STUN_ERROR_REASON_SERVER_ERROR), error_attr->reason());
1499 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL);
1500 EXPECT_TRUE(StunMessage::ValidateMessageIntegrity(
1501 rport->last_stun_buf()->Data(), rport->last_stun_buf()->Length(),
1502 "rpass"));
1503 EXPECT_TRUE(msg->GetUInt32(STUN_ATTR_FINGERPRINT) != NULL);
1504 EXPECT_TRUE(StunMessage::ValidateFingerprint(
1505 lport->last_stun_buf()->Data(), lport->last_stun_buf()->Length()));
1506 // No USERNAME with ICE.
1507 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USERNAME) == NULL);
1508 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_PRIORITY) == NULL);
1509
1510 // Testing STUN binding requests from rport --> lport, having ICE_CONTROLLED
1511 // and (incremented) RETRANSMIT_COUNT attributes.
1512 rport->Reset();
1513 rport->set_send_retransmit_count_attribute(true);
1514 rconn->Ping(0);
1515 rconn->Ping(0);
1516 rconn->Ping(0);
1517 ASSERT_TRUE_WAIT(rport->last_stun_msg() != NULL, 1000);
1518 msg = rport->last_stun_msg();
1519 EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
1520 const StunUInt64Attribute* ice_controlled_attr =
1521 msg->GetUInt64(STUN_ATTR_ICE_CONTROLLED);
1522 ASSERT_TRUE(ice_controlled_attr != NULL);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00001523 EXPECT_EQ(rport->IceTiebreaker(), ice_controlled_attr->value());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001524 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) == NULL);
1525
1526 // Request should include ping count.
1527 const StunUInt32Attribute* retransmit_attr =
1528 msg->GetUInt32(STUN_ATTR_RETRANSMIT_COUNT);
1529 ASSERT_TRUE(retransmit_attr != NULL);
1530 EXPECT_EQ(2U, retransmit_attr->value());
1531
1532 // Respond with a BINDING-RESPONSE.
1533 request.reset(CopyStunMessage(msg));
1534 lport->SendBindingResponse(request.get(), rport->Candidates()[0].address());
1535 msg = lport->last_stun_msg();
1536
1537 // Response should include same ping count.
1538 retransmit_attr = msg->GetUInt32(STUN_ATTR_RETRANSMIT_COUNT);
1539 ASSERT_TRUE(retransmit_attr != NULL);
1540 EXPECT_EQ(2U, retransmit_attr->value());
1541}
1542
1543TEST_F(PortTest, TestUseCandidateAttribute) {
1544 talk_base::scoped_ptr<TestPort> lport(
1545 CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
1546 talk_base::scoped_ptr<TestPort> rport(
1547 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1548 lport->SetIceProtocolType(ICEPROTO_RFC5245);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00001549 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1550 lport->SetIceTiebreaker(kTiebreaker1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001551 rport->SetIceProtocolType(ICEPROTO_RFC5245);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00001552 rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
1553 rport->SetIceTiebreaker(kTiebreaker2);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001554
1555 // Send a fake ping from lport to rport.
1556 lport->PrepareAddress();
1557 rport->PrepareAddress();
1558 ASSERT_FALSE(rport->Candidates().empty());
1559 Connection* lconn = lport->CreateConnection(
1560 rport->Candidates()[0], Port::ORIGIN_MESSAGE);
1561 lconn->Ping(0);
1562 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, 1000);
1563 IceMessage* msg = lport->last_stun_msg();
1564 const StunUInt64Attribute* ice_controlling_attr =
1565 msg->GetUInt64(STUN_ATTR_ICE_CONTROLLING);
1566 ASSERT_TRUE(ice_controlling_attr != NULL);
1567 const StunByteStringAttribute* use_candidate_attr = msg->GetByteString(
1568 STUN_ATTR_USE_CANDIDATE);
1569 ASSERT_TRUE(use_candidate_attr != NULL);
1570}
1571
1572// Test handling STUN messages in GICE format.
1573TEST_F(PortTest, TestHandleStunMessageAsGice) {
1574 // Our port will act as the "remote" port.
1575 talk_base::scoped_ptr<TestPort> port(
1576 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1577 port->SetIceProtocolType(ICEPROTO_GOOGLE);
1578
1579 talk_base::scoped_ptr<IceMessage> in_msg, out_msg;
1580 talk_base::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
1581 talk_base::SocketAddress addr(kLocalAddr1);
1582 std::string username;
1583
1584 // BINDING-REQUEST from local to remote with valid GICE username and no M-I.
1585 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
1586 "rfraglfrag"));
1587 WriteStunMessage(in_msg.get(), buf.get());
1588 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1589 out_msg.accept(), &username));
1590 EXPECT_TRUE(out_msg.get() != NULL); // Succeeds, since this is GICE.
1591 EXPECT_EQ("lfrag", username);
1592
1593 // Add M-I; should be ignored and rest of message parsed normally.
1594 in_msg->AddMessageIntegrity("password");
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);
1599 EXPECT_EQ("lfrag", username);
1600
1601 // BINDING-RESPONSE with username, as done in GICE. Should succeed.
1602 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_RESPONSE,
1603 "rfraglfrag"));
1604 in_msg->AddAttribute(
1605 new StunAddressAttribute(STUN_ATTR_MAPPED_ADDRESS, kLocalAddr2));
1606 WriteStunMessage(in_msg.get(), buf.get());
1607 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1608 out_msg.accept(), &username));
1609 EXPECT_TRUE(out_msg.get() != NULL);
1610 EXPECT_EQ("", username);
1611
1612 // BINDING-RESPONSE without username. Should be tolerated as well.
1613 in_msg.reset(CreateStunMessage(STUN_BINDING_RESPONSE));
1614 in_msg->AddAttribute(
1615 new StunAddressAttribute(STUN_ATTR_MAPPED_ADDRESS, kLocalAddr2));
1616 WriteStunMessage(in_msg.get(), buf.get());
1617 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1618 out_msg.accept(), &username));
1619 EXPECT_TRUE(out_msg.get() != NULL);
1620 EXPECT_EQ("", username);
1621
1622 // BINDING-ERROR-RESPONSE with username and error code.
1623 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_ERROR_RESPONSE,
1624 "rfraglfrag"));
1625 in_msg->AddAttribute(new StunErrorCodeAttribute(STUN_ATTR_ERROR_CODE,
1626 STUN_ERROR_SERVER_ERROR_AS_GICE, STUN_ERROR_REASON_SERVER_ERROR));
1627 WriteStunMessage(in_msg.get(), buf.get());
1628 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1629 out_msg.accept(), &username));
1630 ASSERT_TRUE(out_msg.get() != NULL);
1631 EXPECT_EQ("", username);
1632 ASSERT_TRUE(out_msg->GetErrorCode() != NULL);
1633 // GetStunMessage doesn't unmunge the GICE error code (happens downstream).
1634 EXPECT_EQ(STUN_ERROR_SERVER_ERROR_AS_GICE, out_msg->GetErrorCode()->code());
1635 EXPECT_EQ(std::string(STUN_ERROR_REASON_SERVER_ERROR),
1636 out_msg->GetErrorCode()->reason());
1637}
1638
1639// Test handling STUN messages in ICE format.
1640TEST_F(PortTest, TestHandleStunMessageAsIce) {
1641 // Our port will act as the "remote" port.
1642 talk_base::scoped_ptr<TestPort> port(
1643 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1644 port->SetIceProtocolType(ICEPROTO_RFC5245);
1645
1646 talk_base::scoped_ptr<IceMessage> in_msg, out_msg;
1647 talk_base::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
1648 talk_base::SocketAddress addr(kLocalAddr1);
1649 std::string username;
1650
1651 // BINDING-REQUEST from local to remote with valid ICE username,
1652 // MESSAGE-INTEGRITY, and FINGERPRINT.
1653 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
1654 "rfrag:lfrag"));
1655 in_msg->AddMessageIntegrity("rpass");
1656 in_msg->AddFingerprint();
1657 WriteStunMessage(in_msg.get(), buf.get());
1658 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1659 out_msg.accept(), &username));
1660 EXPECT_TRUE(out_msg.get() != NULL);
1661 EXPECT_EQ("lfrag", username);
1662
1663 // BINDING-RESPONSE without username, with MESSAGE-INTEGRITY and FINGERPRINT.
1664 in_msg.reset(CreateStunMessage(STUN_BINDING_RESPONSE));
1665 in_msg->AddAttribute(
1666 new StunXorAddressAttribute(STUN_ATTR_XOR_MAPPED_ADDRESS, kLocalAddr2));
1667 in_msg->AddMessageIntegrity("rpass");
1668 in_msg->AddFingerprint();
1669 WriteStunMessage(in_msg.get(), buf.get());
1670 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1671 out_msg.accept(), &username));
1672 EXPECT_TRUE(out_msg.get() != NULL);
1673 EXPECT_EQ("", username);
1674
1675 // BINDING-ERROR-RESPONSE without username, with error, M-I, and FINGERPRINT.
1676 in_msg.reset(CreateStunMessage(STUN_BINDING_ERROR_RESPONSE));
1677 in_msg->AddAttribute(new StunErrorCodeAttribute(STUN_ATTR_ERROR_CODE,
1678 STUN_ERROR_SERVER_ERROR, STUN_ERROR_REASON_SERVER_ERROR));
1679 in_msg->AddFingerprint();
1680 WriteStunMessage(in_msg.get(), buf.get());
1681 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1682 out_msg.accept(), &username));
1683 EXPECT_TRUE(out_msg.get() != NULL);
1684 EXPECT_EQ("", username);
1685 ASSERT_TRUE(out_msg->GetErrorCode() != NULL);
1686 EXPECT_EQ(STUN_ERROR_SERVER_ERROR, out_msg->GetErrorCode()->code());
1687 EXPECT_EQ(std::string(STUN_ERROR_REASON_SERVER_ERROR),
1688 out_msg->GetErrorCode()->reason());
1689}
1690
mallinath@webrtc.org67ee6b92014-02-03 16:57:16 +00001691// This test verifies port can handle ICE messages in Hybrid mode and switches
1692// ICEPROTO_RFC5245 mode after successfully handling the message.
1693TEST_F(PortTest, TestHandleStunMessageAsIceInHybridMode) {
1694 // Our port will act as the "remote" port.
1695 talk_base::scoped_ptr<TestPort> port(
1696 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1697 port->SetIceProtocolType(ICEPROTO_HYBRID);
1698
1699 talk_base::scoped_ptr<IceMessage> in_msg, out_msg;
1700 talk_base::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
1701 talk_base::SocketAddress addr(kLocalAddr1);
1702 std::string username;
1703
1704 // BINDING-REQUEST from local to remote with valid ICE username,
1705 // MESSAGE-INTEGRITY, and FINGERPRINT.
1706 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
1707 "rfrag:lfrag"));
1708 in_msg->AddMessageIntegrity("rpass");
1709 in_msg->AddFingerprint();
1710 WriteStunMessage(in_msg.get(), buf.get());
1711 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1712 out_msg.accept(), &username));
1713 EXPECT_TRUE(out_msg.get() != NULL);
1714 EXPECT_EQ("lfrag", username);
1715 EXPECT_EQ(ICEPROTO_RFC5245, port->IceProtocol());
1716}
1717
1718// This test verifies port can handle GICE messages in Hybrid mode and switches
1719// ICEPROTO_GOOGLE mode after successfully handling the message.
1720TEST_F(PortTest, TestHandleStunMessageAsGiceInHybridMode) {
1721 // Our port will act as the "remote" port.
1722 talk_base::scoped_ptr<TestPort> port(
1723 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1724 port->SetIceProtocolType(ICEPROTO_HYBRID);
1725
1726 talk_base::scoped_ptr<IceMessage> in_msg, out_msg;
1727 talk_base::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
1728 talk_base::SocketAddress addr(kLocalAddr1);
1729 std::string username;
1730
1731 // BINDING-REQUEST from local to remote with valid GICE username and no M-I.
1732 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
1733 "rfraglfrag"));
1734 WriteStunMessage(in_msg.get(), buf.get());
1735 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1736 out_msg.accept(), &username));
1737 EXPECT_TRUE(out_msg.get() != NULL); // Succeeds, since this is GICE.
1738 EXPECT_EQ("lfrag", username);
1739 EXPECT_EQ(ICEPROTO_GOOGLE, port->IceProtocol());
1740}
1741
1742// Verify port is not switched out of RFC5245 mode if GICE message is received
1743// in that mode.
1744TEST_F(PortTest, TestHandleStunMessageAsGiceInIceMode) {
1745 // Our port will act as the "remote" port.
1746 talk_base::scoped_ptr<TestPort> port(
1747 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1748 port->SetIceProtocolType(ICEPROTO_RFC5245);
1749
1750 talk_base::scoped_ptr<IceMessage> in_msg, out_msg;
1751 talk_base::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
1752 talk_base::SocketAddress addr(kLocalAddr1);
1753 std::string username;
1754
1755 // BINDING-REQUEST from local to remote with valid GICE username and no M-I.
1756 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
1757 "rfraglfrag"));
1758 WriteStunMessage(in_msg.get(), buf.get());
1759 // Should fail as there is no MI and fingerprint.
1760 EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1761 out_msg.accept(), &username));
1762 EXPECT_EQ(ICEPROTO_RFC5245, port->IceProtocol());
1763}
1764
1765
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001766// Tests handling of GICE binding requests with missing or incorrect usernames.
1767TEST_F(PortTest, TestHandleStunMessageAsGiceBadUsername) {
1768 talk_base::scoped_ptr<TestPort> port(
1769 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1770 port->SetIceProtocolType(ICEPROTO_GOOGLE);
1771
1772 talk_base::scoped_ptr<IceMessage> in_msg, out_msg;
1773 talk_base::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
1774 talk_base::SocketAddress addr(kLocalAddr1);
1775 std::string username;
1776
1777 // BINDING-REQUEST with no username.
1778 in_msg.reset(CreateStunMessage(STUN_BINDING_REQUEST));
1779 WriteStunMessage(in_msg.get(), buf.get());
1780 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1781 out_msg.accept(), &username));
1782 EXPECT_TRUE(out_msg.get() == NULL);
1783 EXPECT_EQ("", username);
1784 EXPECT_EQ(STUN_ERROR_BAD_REQUEST_AS_GICE, port->last_stun_error_code());
1785
1786 // BINDING-REQUEST with empty username.
1787 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST, ""));
1788 WriteStunMessage(in_msg.get(), buf.get());
1789 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1790 out_msg.accept(), &username));
1791 EXPECT_TRUE(out_msg.get() == NULL);
1792 EXPECT_EQ("", username);
1793 EXPECT_EQ(STUN_ERROR_UNAUTHORIZED_AS_GICE, port->last_stun_error_code());
1794
1795 // BINDING-REQUEST with too-short username.
1796 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST, "lfra"));
1797 WriteStunMessage(in_msg.get(), buf.get());
1798 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1799 out_msg.accept(), &username));
1800 EXPECT_TRUE(out_msg.get() == NULL);
1801 EXPECT_EQ("", username);
1802 EXPECT_EQ(STUN_ERROR_UNAUTHORIZED_AS_GICE, port->last_stun_error_code());
1803
1804 // BINDING-REQUEST with reversed username.
1805 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
1806 "lfragrfrag"));
1807 WriteStunMessage(in_msg.get(), buf.get());
1808 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1809 out_msg.accept(), &username));
1810 EXPECT_TRUE(out_msg.get() == NULL);
1811 EXPECT_EQ("", username);
1812 EXPECT_EQ(STUN_ERROR_UNAUTHORIZED_AS_GICE, port->last_stun_error_code());
1813
1814 // BINDING-REQUEST with garbage username.
1815 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
1816 "abcdefgh"));
1817 WriteStunMessage(in_msg.get(), buf.get());
1818 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1819 out_msg.accept(), &username));
1820 EXPECT_TRUE(out_msg.get() == NULL);
1821 EXPECT_EQ("", username);
1822 EXPECT_EQ(STUN_ERROR_UNAUTHORIZED_AS_GICE, port->last_stun_error_code());
1823}
1824
1825// Tests handling of ICE binding requests with missing or incorrect usernames.
1826TEST_F(PortTest, TestHandleStunMessageAsIceBadUsername) {
1827 talk_base::scoped_ptr<TestPort> port(
1828 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1829 port->SetIceProtocolType(ICEPROTO_RFC5245);
1830
1831 talk_base::scoped_ptr<IceMessage> in_msg, out_msg;
1832 talk_base::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
1833 talk_base::SocketAddress addr(kLocalAddr1);
1834 std::string username;
1835
1836 // BINDING-REQUEST with no username.
1837 in_msg.reset(CreateStunMessage(STUN_BINDING_REQUEST));
1838 in_msg->AddMessageIntegrity("rpass");
1839 in_msg->AddFingerprint();
1840 WriteStunMessage(in_msg.get(), buf.get());
1841 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1842 out_msg.accept(), &username));
1843 EXPECT_TRUE(out_msg.get() == NULL);
1844 EXPECT_EQ("", username);
1845 EXPECT_EQ(STUN_ERROR_BAD_REQUEST, port->last_stun_error_code());
1846
1847 // BINDING-REQUEST with empty username.
1848 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST, ""));
1849 in_msg->AddMessageIntegrity("rpass");
1850 in_msg->AddFingerprint();
1851 WriteStunMessage(in_msg.get(), buf.get());
1852 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1853 out_msg.accept(), &username));
1854 EXPECT_TRUE(out_msg.get() == NULL);
1855 EXPECT_EQ("", username);
1856 EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
1857
1858 // BINDING-REQUEST with too-short username.
1859 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST, "rfra"));
1860 in_msg->AddMessageIntegrity("rpass");
1861 in_msg->AddFingerprint();
1862 WriteStunMessage(in_msg.get(), buf.get());
1863 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1864 out_msg.accept(), &username));
1865 EXPECT_TRUE(out_msg.get() == NULL);
1866 EXPECT_EQ("", username);
1867 EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
1868
1869 // BINDING-REQUEST with reversed username.
1870 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
1871 "lfrag:rfrag"));
1872 in_msg->AddMessageIntegrity("rpass");
1873 in_msg->AddFingerprint();
1874 WriteStunMessage(in_msg.get(), buf.get());
1875 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1876 out_msg.accept(), &username));
1877 EXPECT_TRUE(out_msg.get() == NULL);
1878 EXPECT_EQ("", username);
1879 EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
1880
1881 // BINDING-REQUEST with garbage username.
1882 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
1883 "abcd:efgh"));
1884 in_msg->AddMessageIntegrity("rpass");
1885 in_msg->AddFingerprint();
1886 WriteStunMessage(in_msg.get(), buf.get());
1887 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1888 out_msg.accept(), &username));
1889 EXPECT_TRUE(out_msg.get() == NULL);
1890 EXPECT_EQ("", username);
1891 EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
1892}
1893
1894// Test handling STUN messages (as ICE) with missing or malformed M-I.
1895TEST_F(PortTest, TestHandleStunMessageAsIceBadMessageIntegrity) {
1896 // Our port will act as the "remote" port.
1897 talk_base::scoped_ptr<TestPort> port(
1898 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1899 port->SetIceProtocolType(ICEPROTO_RFC5245);
1900
1901 talk_base::scoped_ptr<IceMessage> in_msg, out_msg;
1902 talk_base::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
1903 talk_base::SocketAddress addr(kLocalAddr1);
1904 std::string username;
1905
1906 // BINDING-REQUEST from local to remote with valid ICE username and
1907 // FINGERPRINT, but no MESSAGE-INTEGRITY.
1908 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
1909 "rfrag:lfrag"));
1910 in_msg->AddFingerprint();
1911 WriteStunMessage(in_msg.get(), buf.get());
1912 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1913 out_msg.accept(), &username));
1914 EXPECT_TRUE(out_msg.get() == NULL);
1915 EXPECT_EQ("", username);
1916 EXPECT_EQ(STUN_ERROR_BAD_REQUEST, port->last_stun_error_code());
1917
1918 // BINDING-REQUEST from local to remote with valid ICE username and
1919 // FINGERPRINT, but invalid MESSAGE-INTEGRITY.
1920 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
1921 "rfrag:lfrag"));
1922 in_msg->AddMessageIntegrity("invalid");
1923 in_msg->AddFingerprint();
1924 WriteStunMessage(in_msg.get(), buf.get());
1925 EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1926 out_msg.accept(), &username));
1927 EXPECT_TRUE(out_msg.get() == NULL);
1928 EXPECT_EQ("", username);
1929 EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
1930
1931 // TODO: BINDING-RESPONSES and BINDING-ERROR-RESPONSES are checked
1932 // by the Connection, not the Port, since they require the remote username.
1933 // Change this test to pass in data via Connection::OnReadPacket instead.
1934}
1935
1936// Test handling STUN messages (as ICE) with missing or malformed FINGERPRINT.
1937TEST_F(PortTest, TestHandleStunMessageAsIceBadFingerprint) {
1938 // Our port will act as the "remote" port.
1939 talk_base::scoped_ptr<TestPort> port(
1940 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1941 port->SetIceProtocolType(ICEPROTO_RFC5245);
1942
1943 talk_base::scoped_ptr<IceMessage> in_msg, out_msg;
1944 talk_base::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
1945 talk_base::SocketAddress addr(kLocalAddr1);
1946 std::string username;
1947
1948 // BINDING-REQUEST from local to remote with valid ICE username and
1949 // MESSAGE-INTEGRITY, but no FINGERPRINT; GetStunMessage should fail.
1950 in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
1951 "rfrag:lfrag"));
1952 in_msg->AddMessageIntegrity("rpass");
1953 WriteStunMessage(in_msg.get(), buf.get());
1954 EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1955 out_msg.accept(), &username));
1956 EXPECT_EQ(0, port->last_stun_error_code());
1957
1958 // Now, add a fingerprint, but munge the message so it's not valid.
1959 in_msg->AddFingerprint();
1960 in_msg->SetTransactionID("TESTTESTBADD");
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 // Valid BINDING-RESPONSE, except no FINGERPRINT.
1967 in_msg.reset(CreateStunMessage(STUN_BINDING_RESPONSE));
1968 in_msg->AddAttribute(
1969 new StunXorAddressAttribute(STUN_ATTR_XOR_MAPPED_ADDRESS, kLocalAddr2));
1970 in_msg->AddMessageIntegrity("rpass");
1971 WriteStunMessage(in_msg.get(), buf.get());
1972 EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1973 out_msg.accept(), &username));
1974 EXPECT_EQ(0, port->last_stun_error_code());
1975
1976 // Now, add a fingerprint, but munge the message so it's not valid.
1977 in_msg->AddFingerprint();
1978 in_msg->SetTransactionID("TESTTESTBADD");
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 // Valid BINDING-ERROR-RESPONSE, except no FINGERPRINT.
1985 in_msg.reset(CreateStunMessage(STUN_BINDING_ERROR_RESPONSE));
1986 in_msg->AddAttribute(new StunErrorCodeAttribute(STUN_ATTR_ERROR_CODE,
1987 STUN_ERROR_SERVER_ERROR, STUN_ERROR_REASON_SERVER_ERROR));
1988 in_msg->AddMessageIntegrity("rpass");
1989 WriteStunMessage(in_msg.get(), buf.get());
1990 EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1991 out_msg.accept(), &username));
1992 EXPECT_EQ(0, port->last_stun_error_code());
1993
1994 // Now, add a fingerprint, but munge the message so it's not valid.
1995 in_msg->AddFingerprint();
1996 in_msg->SetTransactionID("TESTTESTBADD");
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
2003// Test handling of STUN binding indication messages (as ICE). STUN binding
2004// indications are allowed only to the connection which is in read mode.
2005TEST_F(PortTest, TestHandleStunBindingIndication) {
2006 talk_base::scoped_ptr<TestPort> lport(
2007 CreateTestPort(kLocalAddr2, "lfrag", "lpass"));
2008 lport->SetIceProtocolType(ICEPROTO_RFC5245);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00002009 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
2010 lport->SetIceTiebreaker(kTiebreaker1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002011
2012 // Verifying encoding and decoding STUN indication message.
2013 talk_base::scoped_ptr<IceMessage> in_msg, out_msg;
2014 talk_base::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
2015 talk_base::SocketAddress addr(kLocalAddr1);
2016 std::string username;
2017
2018 in_msg.reset(CreateStunMessage(STUN_BINDING_INDICATION));
2019 in_msg->AddFingerprint();
2020 WriteStunMessage(in_msg.get(), buf.get());
2021 EXPECT_TRUE(lport->GetStunMessage(buf->Data(), buf->Length(), addr,
2022 out_msg.accept(), &username));
2023 EXPECT_TRUE(out_msg.get() != NULL);
2024 EXPECT_EQ(out_msg->type(), STUN_BINDING_INDICATION);
2025 EXPECT_EQ("", username);
2026
2027 // Verify connection can handle STUN indication and updates
2028 // last_ping_received.
2029 talk_base::scoped_ptr<TestPort> rport(
2030 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
2031 rport->SetIceProtocolType(ICEPROTO_RFC5245);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00002032 rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
2033 rport->SetIceTiebreaker(kTiebreaker2);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002034
2035 lport->PrepareAddress();
2036 rport->PrepareAddress();
2037 ASSERT_FALSE(lport->Candidates().empty());
2038 ASSERT_FALSE(rport->Candidates().empty());
2039
2040 Connection* lconn = lport->CreateConnection(rport->Candidates()[0],
2041 Port::ORIGIN_MESSAGE);
2042 Connection* rconn = rport->CreateConnection(lport->Candidates()[0],
2043 Port::ORIGIN_MESSAGE);
2044 rconn->Ping(0);
2045
2046 ASSERT_TRUE_WAIT(rport->last_stun_msg() != NULL, 1000);
2047 IceMessage* msg = rport->last_stun_msg();
2048 EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
2049 // Send rport binding request to lport.
2050 lconn->OnReadPacket(rport->last_stun_buf()->Data(),
wu@webrtc.orga9890802013-12-13 00:21:03 +00002051 rport->last_stun_buf()->Length(),
2052 talk_base::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002053 ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, 1000);
2054 EXPECT_EQ(STUN_BINDING_RESPONSE, lport->last_stun_msg()->type());
2055 uint32 last_ping_received1 = lconn->last_ping_received();
2056
2057 // Adding a delay of 100ms.
2058 talk_base::Thread::Current()->ProcessMessages(100);
2059 // Pinging lconn using stun indication message.
wu@webrtc.orga9890802013-12-13 00:21:03 +00002060 lconn->OnReadPacket(buf->Data(), buf->Length(), talk_base::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002061 uint32 last_ping_received2 = lconn->last_ping_received();
2062 EXPECT_GT(last_ping_received2, last_ping_received1);
2063}
2064
2065TEST_F(PortTest, TestComputeCandidatePriority) {
2066 talk_base::scoped_ptr<TestPort> port(
2067 CreateTestPort(kLocalAddr1, "name", "pass"));
2068 port->set_type_preference(90);
2069 port->set_component(177);
2070 port->AddCandidateAddress(SocketAddress("192.168.1.4", 1234));
2071 port->AddCandidateAddress(SocketAddress("2001:db8::1234", 1234));
2072 port->AddCandidateAddress(SocketAddress("fc12:3456::1234", 1234));
2073 port->AddCandidateAddress(SocketAddress("::ffff:192.168.1.4", 1234));
2074 port->AddCandidateAddress(SocketAddress("::192.168.1.4", 1234));
2075 port->AddCandidateAddress(SocketAddress("2002::1234:5678", 1234));
2076 port->AddCandidateAddress(SocketAddress("2001::1234:5678", 1234));
2077 port->AddCandidateAddress(SocketAddress("fecf::1234:5678", 1234));
2078 port->AddCandidateAddress(SocketAddress("3ffe::1234:5678", 1234));
2079 // These should all be:
2080 // (90 << 24) | ([rfc3484 pref value] << 8) | (256 - 177)
2081 uint32 expected_priority_v4 = 1509957199U;
2082 uint32 expected_priority_v6 = 1509959759U;
2083 uint32 expected_priority_ula = 1509962319U;
2084 uint32 expected_priority_v4mapped = expected_priority_v4;
2085 uint32 expected_priority_v4compat = 1509949775U;
2086 uint32 expected_priority_6to4 = 1509954639U;
2087 uint32 expected_priority_teredo = 1509952079U;
2088 uint32 expected_priority_sitelocal = 1509949775U;
2089 uint32 expected_priority_6bone = 1509949775U;
2090 ASSERT_EQ(expected_priority_v4, port->Candidates()[0].priority());
2091 ASSERT_EQ(expected_priority_v6, port->Candidates()[1].priority());
2092 ASSERT_EQ(expected_priority_ula, port->Candidates()[2].priority());
2093 ASSERT_EQ(expected_priority_v4mapped, port->Candidates()[3].priority());
2094 ASSERT_EQ(expected_priority_v4compat, port->Candidates()[4].priority());
2095 ASSERT_EQ(expected_priority_6to4, port->Candidates()[5].priority());
2096 ASSERT_EQ(expected_priority_teredo, port->Candidates()[6].priority());
2097 ASSERT_EQ(expected_priority_sitelocal, port->Candidates()[7].priority());
2098 ASSERT_EQ(expected_priority_6bone, port->Candidates()[8].priority());
2099}
2100
2101TEST_F(PortTest, TestPortProxyProperties) {
2102 talk_base::scoped_ptr<TestPort> port(
2103 CreateTestPort(kLocalAddr1, "name", "pass"));
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00002104 port->SetIceRole(cricket::ICEROLE_CONTROLLING);
2105 port->SetIceTiebreaker(kTiebreaker1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002106
2107 // Create a proxy port.
2108 talk_base::scoped_ptr<PortProxy> proxy(new PortProxy());
2109 proxy->set_impl(port.get());
2110 EXPECT_EQ(port->Type(), proxy->Type());
2111 EXPECT_EQ(port->Network(), proxy->Network());
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00002112 EXPECT_EQ(port->GetIceRole(), proxy->GetIceRole());
2113 EXPECT_EQ(port->IceTiebreaker(), proxy->IceTiebreaker());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002114}
2115
2116// In the case of shared socket, one port may be shared by local and stun.
2117// Test that candidates with different types will have different foundation.
2118TEST_F(PortTest, TestFoundation) {
2119 talk_base::scoped_ptr<TestPort> testport(
2120 CreateTestPort(kLocalAddr1, "name", "pass"));
2121 testport->AddCandidateAddress(kLocalAddr1, kLocalAddr1,
2122 LOCAL_PORT_TYPE,
2123 cricket::ICE_TYPE_PREFERENCE_HOST, false);
2124 testport->AddCandidateAddress(kLocalAddr2, kLocalAddr1,
2125 STUN_PORT_TYPE,
2126 cricket::ICE_TYPE_PREFERENCE_SRFLX, true);
2127 EXPECT_NE(testport->Candidates()[0].foundation(),
2128 testport->Candidates()[1].foundation());
2129}
2130
2131// This test verifies the foundation of different types of ICE candidates.
2132TEST_F(PortTest, TestCandidateFoundation) {
2133 talk_base::scoped_ptr<talk_base::NATServer> nat_server(
2134 CreateNatServer(kNatAddr1, NAT_OPEN_CONE));
2135 talk_base::scoped_ptr<UDPPort> udpport1(CreateUdpPort(kLocalAddr1));
2136 udpport1->PrepareAddress();
2137 talk_base::scoped_ptr<UDPPort> udpport2(CreateUdpPort(kLocalAddr1));
2138 udpport2->PrepareAddress();
2139 EXPECT_EQ(udpport1->Candidates()[0].foundation(),
2140 udpport2->Candidates()[0].foundation());
2141 talk_base::scoped_ptr<TCPPort> tcpport1(CreateTcpPort(kLocalAddr1));
2142 tcpport1->PrepareAddress();
2143 talk_base::scoped_ptr<TCPPort> tcpport2(CreateTcpPort(kLocalAddr1));
2144 tcpport2->PrepareAddress();
2145 EXPECT_EQ(tcpport1->Candidates()[0].foundation(),
2146 tcpport2->Candidates()[0].foundation());
2147 talk_base::scoped_ptr<Port> stunport(
2148 CreateStunPort(kLocalAddr1, nat_socket_factory1()));
2149 stunport->PrepareAddress();
2150 ASSERT_EQ_WAIT(1U, stunport->Candidates().size(), kTimeout);
2151 EXPECT_NE(tcpport1->Candidates()[0].foundation(),
2152 stunport->Candidates()[0].foundation());
2153 EXPECT_NE(tcpport2->Candidates()[0].foundation(),
2154 stunport->Candidates()[0].foundation());
2155 EXPECT_NE(udpport1->Candidates()[0].foundation(),
2156 stunport->Candidates()[0].foundation());
2157 EXPECT_NE(udpport2->Candidates()[0].foundation(),
2158 stunport->Candidates()[0].foundation());
2159 // Verify GTURN candidate foundation.
2160 talk_base::scoped_ptr<RelayPort> relayport(
2161 CreateGturnPort(kLocalAddr1));
2162 relayport->AddServerAddress(
2163 cricket::ProtocolAddress(kRelayUdpIntAddr, cricket::PROTO_UDP));
2164 relayport->PrepareAddress();
2165 ASSERT_EQ_WAIT(1U, relayport->Candidates().size(), kTimeout);
2166 EXPECT_NE(udpport1->Candidates()[0].foundation(),
2167 relayport->Candidates()[0].foundation());
2168 EXPECT_NE(udpport2->Candidates()[0].foundation(),
2169 relayport->Candidates()[0].foundation());
2170 // Verifying TURN candidate foundation.
2171 talk_base::scoped_ptr<Port> turnport(CreateTurnPort(
2172 kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
2173 turnport->PrepareAddress();
buildbot@webrtc.orgf875f152014-04-14 16:06:21 +00002174 ASSERT_EQ_WAIT(2U, turnport->Candidates().size(), kTimeout);
2175 EXPECT_NE(turnport->Candidates()[0].foundation(),
2176 turnport->Candidates()[1].foundation());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002177 EXPECT_NE(udpport1->Candidates()[0].foundation(),
buildbot@webrtc.orgf875f152014-04-14 16:06:21 +00002178 turnport->Candidates()[1].foundation());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002179 EXPECT_NE(udpport2->Candidates()[0].foundation(),
buildbot@webrtc.orgf875f152014-04-14 16:06:21 +00002180 turnport->Candidates()[1].foundation());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002181 EXPECT_NE(stunport->Candidates()[0].foundation(),
buildbot@webrtc.orgf875f152014-04-14 16:06:21 +00002182 turnport->Candidates()[1].foundation());
2183 EXPECT_EQ(stunport->Candidates()[0].foundation(),
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002184 turnport->Candidates()[0].foundation());
2185}
2186
2187// This test verifies the related addresses of different types of
2188// ICE candiates.
2189TEST_F(PortTest, TestCandidateRelatedAddress) {
2190 talk_base::scoped_ptr<talk_base::NATServer> nat_server(
2191 CreateNatServer(kNatAddr1, NAT_OPEN_CONE));
2192 talk_base::scoped_ptr<UDPPort> udpport(CreateUdpPort(kLocalAddr1));
2193 udpport->PrepareAddress();
2194 // For UDPPort, related address will be empty.
2195 EXPECT_TRUE(udpport->Candidates()[0].related_address().IsNil());
2196 // Testing related address for stun candidates.
2197 // For stun candidate related address must be equal to the base
2198 // socket address.
2199 talk_base::scoped_ptr<StunPort> stunport(
2200 CreateStunPort(kLocalAddr1, nat_socket_factory1()));
2201 stunport->PrepareAddress();
2202 ASSERT_EQ_WAIT(1U, stunport->Candidates().size(), kTimeout);
2203 // Check STUN candidate address.
2204 EXPECT_EQ(stunport->Candidates()[0].address().ipaddr(),
2205 kNatAddr1.ipaddr());
2206 // Check STUN candidate related address.
2207 EXPECT_EQ(stunport->Candidates()[0].related_address(),
2208 stunport->GetLocalAddress());
2209 // Verifying the related address for the GTURN candidates.
2210 // NOTE: In case of GTURN related address will be equal to the mapped
2211 // address, but address(mapped) will not be XOR.
2212 talk_base::scoped_ptr<RelayPort> relayport(
2213 CreateGturnPort(kLocalAddr1));
2214 relayport->AddServerAddress(
2215 cricket::ProtocolAddress(kRelayUdpIntAddr, cricket::PROTO_UDP));
2216 relayport->PrepareAddress();
2217 ASSERT_EQ_WAIT(1U, relayport->Candidates().size(), kTimeout);
2218 // For Gturn related address is set to "0.0.0.0:0"
2219 EXPECT_EQ(talk_base::SocketAddress(),
2220 relayport->Candidates()[0].related_address());
2221 // Verifying the related address for TURN candidate.
2222 // For TURN related address must be equal to the mapped address.
2223 talk_base::scoped_ptr<Port> turnport(CreateTurnPort(
2224 kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
2225 turnport->PrepareAddress();
buildbot@webrtc.orgf875f152014-04-14 16:06:21 +00002226 ASSERT_EQ_WAIT(2U, turnport->Candidates().size(), kTimeout);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002227 EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
buildbot@webrtc.orgf875f152014-04-14 16:06:21 +00002228 turnport->Candidates()[1].address().ipaddr());
2229 EXPECT_EQ(kLocalAddr1.ipaddr(),
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002230 turnport->Candidates()[0].related_address().ipaddr());
buildbot@webrtc.orgf875f152014-04-14 16:06:21 +00002231 EXPECT_EQ(kNatAddr1.ipaddr(),
2232 turnport->Candidates()[1].related_address().ipaddr());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002233}
2234
2235// Test priority value overflow handling when preference is set to 3.
2236TEST_F(PortTest, TestCandidatePreference) {
2237 cricket::Candidate cand1;
2238 cand1.set_preference(3);
2239 cricket::Candidate cand2;
2240 cand2.set_preference(1);
2241 EXPECT_TRUE(cand1.preference() > cand2.preference());
2242}
2243
2244// Test the Connection priority is calculated correctly.
2245TEST_F(PortTest, TestConnectionPriority) {
2246 talk_base::scoped_ptr<TestPort> lport(
2247 CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
2248 lport->set_type_preference(cricket::ICE_TYPE_PREFERENCE_HOST);
2249 talk_base::scoped_ptr<TestPort> rport(
2250 CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
2251 rport->set_type_preference(cricket::ICE_TYPE_PREFERENCE_RELAY);
2252 lport->set_component(123);
2253 lport->AddCandidateAddress(SocketAddress("192.168.1.4", 1234));
2254 rport->set_component(23);
2255 rport->AddCandidateAddress(SocketAddress("10.1.1.100", 1234));
2256
2257 EXPECT_EQ(0x7E001E85U, lport->Candidates()[0].priority());
2258 EXPECT_EQ(0x2001EE9U, rport->Candidates()[0].priority());
2259
2260 // RFC 5245
2261 // pair priority = 2^32*MIN(G,D) + 2*MAX(G,D) + (G>D?1:0)
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00002262 lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
2263 rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002264 Connection* lconn = lport->CreateConnection(
2265 rport->Candidates()[0], Port::ORIGIN_MESSAGE);
2266#if defined(WIN32)
2267 EXPECT_EQ(0x2001EE9FC003D0BU, lconn->priority());
2268#else
2269 EXPECT_EQ(0x2001EE9FC003D0BLLU, lconn->priority());
2270#endif
2271
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00002272 lport->SetIceRole(cricket::ICEROLE_CONTROLLED);
2273 rport->SetIceRole(cricket::ICEROLE_CONTROLLING);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002274 Connection* rconn = rport->CreateConnection(
2275 lport->Candidates()[0], Port::ORIGIN_MESSAGE);
2276#if defined(WIN32)
2277 EXPECT_EQ(0x2001EE9FC003D0AU, rconn->priority());
2278#else
2279 EXPECT_EQ(0x2001EE9FC003D0ALLU, rconn->priority());
2280#endif
2281}
2282
2283TEST_F(PortTest, TestWritableState) {
2284 UDPPort* port1 = CreateUdpPort(kLocalAddr1);
2285 UDPPort* port2 = CreateUdpPort(kLocalAddr2);
2286
2287 // Set up channels.
2288 TestChannel ch1(port1, port2);
2289 TestChannel ch2(port2, port1);
2290
2291 // Acquire addresses.
2292 ch1.Start();
2293 ch2.Start();
2294 ASSERT_EQ_WAIT(1, ch1.complete_count(), kTimeout);
2295 ASSERT_EQ_WAIT(1, ch2.complete_count(), kTimeout);
2296
2297 // Send a ping from src to dst.
2298 ch1.CreateConnection();
2299 ASSERT_TRUE(ch1.conn() != NULL);
2300 EXPECT_EQ(Connection::STATE_WRITE_INIT, ch1.conn()->write_state());
2301 EXPECT_TRUE_WAIT(ch1.conn()->connected(), kTimeout); // for TCP connect
2302 ch1.Ping();
2303 WAIT(!ch2.remote_address().IsNil(), kTimeout);
2304
2305 // Data should be unsendable until the connection is accepted.
2306 char data[] = "abcd";
2307 int data_size = ARRAY_SIZE(data);
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00002308 talk_base::PacketOptions options;
2309 EXPECT_EQ(SOCKET_ERROR, ch1.conn()->Send(data, data_size, options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002310
2311 // Accept the connection to return the binding response, transition to
2312 // writable, and allow data to be sent.
2313 ch2.AcceptConnection();
2314 EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch1.conn()->write_state(),
2315 kTimeout);
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00002316 EXPECT_EQ(data_size, ch1.conn()->Send(data, data_size, options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002317
2318 // Ask the connection to update state as if enough time has passed to lose
2319 // full writability and 5 pings went unresponded to. We'll accomplish the
2320 // latter by sending pings but not pumping messages.
2321 for (uint32 i = 1; i <= CONNECTION_WRITE_CONNECT_FAILURES; ++i) {
2322 ch1.Ping(i);
2323 }
2324 uint32 unreliable_timeout_delay = CONNECTION_WRITE_CONNECT_TIMEOUT + 500u;
2325 ch1.conn()->UpdateState(unreliable_timeout_delay);
2326 EXPECT_EQ(Connection::STATE_WRITE_UNRELIABLE, ch1.conn()->write_state());
2327
2328 // Data should be able to be sent in this state.
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00002329 EXPECT_EQ(data_size, ch1.conn()->Send(data, data_size, options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002330
2331 // And now allow the other side to process the pings and send binding
2332 // responses.
2333 EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch1.conn()->write_state(),
2334 kTimeout);
2335
2336 // Wait long enough for a full timeout (past however long we've already
2337 // waited).
2338 for (uint32 i = 1; i <= CONNECTION_WRITE_CONNECT_FAILURES; ++i) {
2339 ch1.Ping(unreliable_timeout_delay + i);
2340 }
2341 ch1.conn()->UpdateState(unreliable_timeout_delay + CONNECTION_WRITE_TIMEOUT +
2342 500u);
2343 EXPECT_EQ(Connection::STATE_WRITE_TIMEOUT, ch1.conn()->write_state());
2344
2345 // Now that the connection has completely timed out, data send should fail.
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00002346 EXPECT_EQ(SOCKET_ERROR, ch1.conn()->Send(data, data_size, options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002347
2348 ch1.Stop();
2349 ch2.Stop();
2350}
2351
2352TEST_F(PortTest, TestTimeoutForNeverWritable) {
2353 UDPPort* port1 = CreateUdpPort(kLocalAddr1);
2354 UDPPort* port2 = CreateUdpPort(kLocalAddr2);
2355
2356 // Set up channels.
2357 TestChannel ch1(port1, port2);
2358 TestChannel ch2(port2, port1);
2359
2360 // Acquire addresses.
2361 ch1.Start();
2362 ch2.Start();
2363
2364 ch1.CreateConnection();
2365 ASSERT_TRUE(ch1.conn() != NULL);
2366 EXPECT_EQ(Connection::STATE_WRITE_INIT, ch1.conn()->write_state());
2367
2368 // Attempt to go directly to write timeout.
2369 for (uint32 i = 1; i <= CONNECTION_WRITE_CONNECT_FAILURES; ++i) {
2370 ch1.Ping(i);
2371 }
2372 ch1.conn()->UpdateState(CONNECTION_WRITE_TIMEOUT + 500u);
2373 EXPECT_EQ(Connection::STATE_WRITE_TIMEOUT, ch1.conn()->write_state());
2374}
2375
2376// This test verifies the connection setup between ICEMODE_FULL
2377// and ICEMODE_LITE.
2378// In this test |ch1| behaves like FULL mode client and we have created
2379// port which responds to the ping message just like LITE client.
2380TEST_F(PortTest, TestIceLiteConnectivity) {
2381 TestPort* ice_full_port = CreateTestPort(
2382 kLocalAddr1, "lfrag", "lpass", cricket::ICEPROTO_RFC5245,
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00002383 cricket::ICEROLE_CONTROLLING, kTiebreaker1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002384
2385 talk_base::scoped_ptr<TestPort> ice_lite_port(CreateTestPort(
2386 kLocalAddr2, "rfrag", "rpass", cricket::ICEPROTO_RFC5245,
mallinath@webrtc.orga5506692013-08-12 21:18:15 +00002387 cricket::ICEROLE_CONTROLLED, kTiebreaker2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002388 // Setup TestChannel. This behaves like FULL mode client.
2389 TestChannel ch1(ice_full_port, ice_lite_port.get());
2390 ch1.SetIceMode(ICEMODE_FULL);
2391
2392 // Start gathering candidates.
2393 ch1.Start();
2394 ice_lite_port->PrepareAddress();
2395
2396 ASSERT_EQ_WAIT(1, ch1.complete_count(), kTimeout);
2397 ASSERT_FALSE(ice_lite_port->Candidates().empty());
2398
2399 ch1.CreateConnection();
2400 ASSERT_TRUE(ch1.conn() != NULL);
2401 EXPECT_EQ(Connection::STATE_WRITE_INIT, ch1.conn()->write_state());
2402
2403 // Send ping from full mode client.
2404 // This ping must not have USE_CANDIDATE_ATTR.
2405 ch1.Ping();
2406
2407 // Verify stun ping is without USE_CANDIDATE_ATTR. Getting message directly
2408 // from port.
2409 ASSERT_TRUE_WAIT(ice_full_port->last_stun_msg() != NULL, 1000);
2410 IceMessage* msg = ice_full_port->last_stun_msg();
2411 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) == NULL);
2412
2413 // Respond with a BINDING-RESPONSE from litemode client.
2414 // NOTE: Ideally we should't create connection at this stage from lite
2415 // port, as it should be done only after receiving ping with USE_CANDIDATE.
2416 // But we need a connection to send a response message.
2417 ice_lite_port->CreateConnection(
2418 ice_full_port->Candidates()[0], cricket::Port::ORIGIN_MESSAGE);
2419 talk_base::scoped_ptr<IceMessage> request(CopyStunMessage(msg));
2420 ice_lite_port->SendBindingResponse(
2421 request.get(), ice_full_port->Candidates()[0].address());
2422
2423 // Feeding the respone message from litemode to the full mode connection.
2424 ch1.conn()->OnReadPacket(ice_lite_port->last_stun_buf()->Data(),
wu@webrtc.orga9890802013-12-13 00:21:03 +00002425 ice_lite_port->last_stun_buf()->Length(),
2426 talk_base::PacketTime());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002427 // Verifying full mode connection becomes writable from the response.
2428 EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch1.conn()->write_state(),
2429 kTimeout);
2430 EXPECT_TRUE_WAIT(ch1.nominated(), kTimeout);
2431
2432 // Clear existing stun messsages. Otherwise we will process old stun
2433 // message right after we send ping.
2434 ice_full_port->Reset();
2435 // Send ping. This must have USE_CANDIDATE_ATTR.
2436 ch1.Ping();
2437 ASSERT_TRUE_WAIT(ice_full_port->last_stun_msg() != NULL, 1000);
2438 msg = ice_full_port->last_stun_msg();
2439 EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) != NULL);
2440 ch1.Stop();
2441}
wu@webrtc.orgf6d6ed02014-01-03 22:08:47 +00002442
2443// This test case verifies that the CONTROLLING port does not time out.
2444TEST_F(PortTest, TestControllingNoTimeout) {
2445 SetIceProtocolType(cricket::ICEPROTO_RFC5245);
2446 UDPPort* port1 = CreateUdpPort(kLocalAddr1);
2447 ConnectToSignalDestroyed(port1);
2448 port1->set_timeout_delay(10); // milliseconds
2449 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
2450 port1->SetIceTiebreaker(kTiebreaker1);
2451
2452 UDPPort* port2 = CreateUdpPort(kLocalAddr2);
2453 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
2454 port2->SetIceTiebreaker(kTiebreaker2);
2455
2456 // Set up channels and ensure both ports will be deleted.
2457 TestChannel ch1(port1, port2);
2458 TestChannel ch2(port2, port1);
2459
2460 // Simulate a connection that succeeds, and then is destroyed.
2461 ConnectAndDisconnectChannels(&ch1, &ch2);
2462
2463 // After the connection is destroyed, the port should not be destroyed.
2464 talk_base::Thread::Current()->ProcessMessages(kTimeout);
2465 EXPECT_FALSE(destroyed());
2466}
2467
2468// This test case verifies that the CONTROLLED port does time out, but only
2469// after connectivity is lost.
2470TEST_F(PortTest, TestControlledTimeout) {
2471 SetIceProtocolType(cricket::ICEPROTO_RFC5245);
2472 UDPPort* port1 = CreateUdpPort(kLocalAddr1);
2473 port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
2474 port1->SetIceTiebreaker(kTiebreaker1);
2475
2476 UDPPort* port2 = CreateUdpPort(kLocalAddr2);
2477 ConnectToSignalDestroyed(port2);
2478 port2->set_timeout_delay(10); // milliseconds
2479 port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
2480 port2->SetIceTiebreaker(kTiebreaker2);
2481
2482 // The connection must not be destroyed before a connection is attempted.
2483 EXPECT_FALSE(destroyed());
2484
2485 port1->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
2486 port2->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
2487
2488 // Set up channels and ensure both ports will be deleted.
2489 TestChannel ch1(port1, port2);
2490 TestChannel ch2(port2, port1);
2491
2492 // Simulate a connection that succeeds, and then is destroyed.
2493 ConnectAndDisconnectChannels(&ch1, &ch2);
2494
2495 // The controlled port should be destroyed after 10 milliseconds.
2496 EXPECT_TRUE_WAIT(destroyed(), kTimeout);
2497}