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