port_unittest.cc revision 0c4e06b4c6107a1b94f764e279e4fb4161e905b0
1269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org/*
2269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
3269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org *
4269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org *  Use of this source code is governed by a BSD-style license
5269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org *  that can be found in the LICENSE file in the root of the source
6269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org *  tree. An additional intellectual property rights grant can be found
7269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org *  in the file PATENTS.  All contributing project authors may
8269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org */
10269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
11269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/p2p/base/basicpacketsocketfactory.h"
12269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/p2p/base/relayport.h"
13269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/p2p/base/stunport.h"
14269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/p2p/base/tcpport.h"
15269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/p2p/base/testrelayserver.h"
16269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/p2p/base/teststunserver.h"
17269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/p2p/base/testturnserver.h"
18269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/p2p/base/transport.h"
19269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/p2p/base/turnport.h"
20269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/base/crc32.h"
21269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/base/gunit.h"
22269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/base/helpers.h"
23269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/base/logging.h"
24269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/base/natserver.h"
25269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/base/natsocketfactory.h"
26269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/base/physicalsocketserver.h"
27269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/base/scoped_ptr.h"
28269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/base/socketaddress.h"
29269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/base/ssladapter.h"
30269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/base/stringutils.h"
31269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/base/thread.h"
32269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#include "webrtc/base/virtualsocketserver.h"
33269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
34269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgusing rtc::AsyncPacketSocket;
35269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgusing rtc::ByteBuffer;
36269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgusing rtc::NATType;
37269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgusing rtc::NAT_OPEN_CONE;
38269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgusing rtc::NAT_ADDR_RESTRICTED;
39269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgusing rtc::NAT_PORT_RESTRICTED;
40269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgusing rtc::NAT_SYMMETRIC;
41269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgusing rtc::PacketSocketFactory;
42269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgusing rtc::scoped_ptr;
43269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgusing rtc::Socket;
44269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgusing rtc::SocketAddress;
45269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgusing namespace cricket;
46269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
47269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgstatic const int kTimeout = 1000;
48269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgstatic const SocketAddress kLocalAddr1("192.168.1.2", 0);
49269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgstatic const SocketAddress kLocalAddr2("192.168.1.3", 0);
50c5d0d95fd8957a7a6645b1196e5f1e9cee33525cdeadbeefstatic const SocketAddress kNatAddr1("77.77.77.77", rtc::NAT_SERVER_UDP_PORT);
51c5d0d95fd8957a7a6645b1196e5f1e9cee33525cdeadbeefstatic const SocketAddress kNatAddr2("88.88.88.88", rtc::NAT_SERVER_UDP_PORT);
52269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgstatic const SocketAddress kStunAddr("99.99.99.1", STUN_SERVER_PORT);
53269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgstatic const SocketAddress kRelayUdpIntAddr("99.99.99.2", 5000);
54269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgstatic const SocketAddress kRelayUdpExtAddr("99.99.99.3", 5001);
55269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgstatic const SocketAddress kRelayTcpIntAddr("99.99.99.2", 5002);
56269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgstatic const SocketAddress kRelayTcpExtAddr("99.99.99.3", 5003);
57269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgstatic const SocketAddress kRelaySslTcpIntAddr("99.99.99.2", 5004);
58269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgstatic const SocketAddress kRelaySslTcpExtAddr("99.99.99.3", 5005);
59269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgstatic const SocketAddress kTurnUdpIntAddr("99.99.99.4", STUN_SERVER_PORT);
60269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgstatic const SocketAddress kTurnUdpExtAddr("99.99.99.5", 0);
61269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgstatic const RelayCredentials kRelayCredentials("test", "test");
62269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
63269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// TODO: Update these when RFC5245 is completely supported.
64269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// Magic value of 30 is from RFC3484, for IPv4 addresses.
650c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boströmstatic const uint32_t kDefaultPrflxPriority =
660c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    ICE_TYPE_PREFERENCE_PRFLX << 24 | 30 << 8 |
670c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    (256 - ICE_CANDIDATE_COMPONENT_DEFAULT);
68269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
69269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgstatic const int kTiebreaker1 = 11111;
70269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgstatic const int kTiebreaker2 = 22222;
71269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
72be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shiehstatic const char* data = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
73be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh
74269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgstatic Candidate GetCandidate(Port* port) {
757cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher  assert(port->Candidates().size() >= 1);
76269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  return port->Candidates()[0];
77269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
78269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
79269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgstatic SocketAddress GetAddress(Port* port) {
80269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  return GetCandidate(port).address();
81269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
82269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
83269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgstatic IceMessage* CopyStunMessage(const IceMessage* src) {
84269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  IceMessage* dst = new IceMessage();
85269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ByteBuffer buf;
86269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  src->Write(&buf);
87269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  dst->Read(&buf);
88269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  return dst;
89269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
90269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
91269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgstatic bool WriteStunMessage(const StunMessage* msg, ByteBuffer* buf) {
92269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  buf->Resize(0);  // clear out any existing buffer contents
93269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  return msg->Write(buf);
94269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
95269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
96269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// Stub port class for testing STUN generation and processing.
97269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgclass TestPort : public Port {
98269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org public:
99332331fb01f8a316ac6d61cf4572478610fb3472pkasting@chromium.org  TestPort(rtc::Thread* thread,
100332331fb01f8a316ac6d61cf4572478610fb3472pkasting@chromium.org           const std::string& type,
101332331fb01f8a316ac6d61cf4572478610fb3472pkasting@chromium.org           rtc::PacketSocketFactory* factory,
102332331fb01f8a316ac6d61cf4572478610fb3472pkasting@chromium.org           rtc::Network* network,
103332331fb01f8a316ac6d61cf4572478610fb3472pkasting@chromium.org           const rtc::IPAddress& ip,
1040c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström           uint16_t min_port,
1050c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström           uint16_t max_port,
106332331fb01f8a316ac6d61cf4572478610fb3472pkasting@chromium.org           const std::string& username_fragment,
107332331fb01f8a316ac6d61cf4572478610fb3472pkasting@chromium.org           const std::string& password)
1080c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström      : Port(thread,
1090c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström             type,
1100c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström             factory,
1110c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström             network,
1120c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström             ip,
1130c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström             min_port,
1140c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström             max_port,
1150c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström             username_fragment,
1160c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström             password) {}
117269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ~TestPort() {}
118269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
119269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Expose GetStunMessage so that we can test it.
120269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  using cricket::Port::GetStunMessage;
121269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
122269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // The last StunMessage that was sent on this Port.
123269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // TODO: Make these const; requires changes to SendXXXXResponse.
124269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ByteBuffer* last_stun_buf() { return last_stun_buf_.get(); }
125269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  IceMessage* last_stun_msg() { return last_stun_msg_.get(); }
126269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  int last_stun_error_code() {
127269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    int code = 0;
128269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    if (last_stun_msg_) {
129269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      const StunErrorCodeAttribute* error_attr = last_stun_msg_->GetErrorCode();
130269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      if (error_attr) {
131269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        code = error_attr->code();
132269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      }
133269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    }
134269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    return code;
135269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
136269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
137269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  virtual void PrepareAddress() {
138269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    rtc::SocketAddress addr(ip(), min_port());
1393d564c10157d7de1d2d4236f4e2a13ff1363d52bGuo-wei Shieh    AddAddress(addr, addr, rtc::SocketAddress(), "udp", "", "", Type(),
140269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org               ICE_TYPE_PREFERENCE_HOST, 0, true);
141269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
142269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
143269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Exposed for testing candidate building.
144269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  void AddCandidateAddress(const rtc::SocketAddress& addr) {
1453d564c10157d7de1d2d4236f4e2a13ff1363d52bGuo-wei Shieh    AddAddress(addr, addr, rtc::SocketAddress(), "udp", "", "", Type(),
146269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org               type_preference_, 0, false);
147269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
148269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  void AddCandidateAddress(const rtc::SocketAddress& addr,
149269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                           const rtc::SocketAddress& base_address,
150269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                           const std::string& type,
151269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                           int type_preference,
152269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                           bool final) {
1533d564c10157d7de1d2d4236f4e2a13ff1363d52bGuo-wei Shieh    AddAddress(addr, base_address, rtc::SocketAddress(), "udp", "", "", type,
154269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org               type_preference, 0, final);
155269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
156269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
157269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  virtual Connection* CreateConnection(const Candidate& remote_candidate,
158269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                       CandidateOrigin origin) {
159269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    Connection* conn = new ProxyConnection(this, 0, remote_candidate);
160269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    AddConnection(conn);
161269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    // Set use-candidate attribute flag as this will add USE-CANDIDATE attribute
162269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    // in STUN binding requests.
163269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    conn->set_use_candidate_attr(true);
164269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    return conn;
165269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
166269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  virtual int SendTo(
167269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      const void* data, size_t size, const rtc::SocketAddress& addr,
168269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      const rtc::PacketOptions& options, bool payload) {
169269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    if (!payload) {
170269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      IceMessage* msg = new IceMessage;
171269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      ByteBuffer* buf = new ByteBuffer(static_cast<const char*>(data), size);
172269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      ByteBuffer::ReadPosition pos(buf->GetReadPosition());
173269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      if (!msg->Read(buf)) {
174269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        delete msg;
175269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        delete buf;
176269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        return -1;
177269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      }
178269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      buf->SetReadPosition(pos);
179269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      last_stun_buf_.reset(buf);
180269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      last_stun_msg_.reset(msg);
181269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    }
182269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    return static_cast<int>(size);
183269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
184269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  virtual int SetOption(rtc::Socket::Option opt, int value) {
185269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    return 0;
186269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
187269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  virtual int GetOption(rtc::Socket::Option opt, int* value) {
188269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    return -1;
189269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
190269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  virtual int GetError() {
191269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    return 0;
192269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
193269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  void Reset() {
194269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    last_stun_buf_.reset();
195269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    last_stun_msg_.reset();
196269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
197269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  void set_type_preference(int type_preference) {
198269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    type_preference_ = type_preference;
199269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
200269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
201269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org private:
202269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<ByteBuffer> last_stun_buf_;
203269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<IceMessage> last_stun_msg_;
204269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  int type_preference_;
205269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org};
206269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
207269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgclass TestChannel : public sigslot::has_slots<> {
208269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org public:
209269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Takes ownership of |p1| (but not |p2|).
2101eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  TestChannel(Port* p1)
2111eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh      : ice_mode_(ICEMODE_FULL),
2121eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh        port_(p1),
2131eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh        complete_count_(0),
2141eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh        conn_(NULL),
2151eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh        remote_request_(),
2161eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh        nominated_(false) {
2171eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh    port_->SignalPortComplete.connect(this, &TestChannel::OnPortComplete);
2181eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh    port_->SignalUnknownAddress.connect(this, &TestChannel::OnUnknownAddress);
2191eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh    port_->SignalDestroyed.connect(this, &TestChannel::OnSrcPortDestroyed);
220269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
221269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
222269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  int complete_count() { return complete_count_; }
223269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Connection* conn() { return conn_; }
224269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  const SocketAddress& remote_address() { return remote_address_; }
225269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  const std::string remote_fragment() { return remote_frag_; }
226269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2271eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  void Start() { port_->PrepareAddress(); }
2281eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  void CreateConnection(const Candidate& remote_candidate) {
2291eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh    conn_ = port_->CreateConnection(remote_candidate, Port::ORIGIN_MESSAGE);
230269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    IceMode remote_ice_mode =
231269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        (ice_mode_ == ICEMODE_FULL) ? ICEMODE_LITE : ICEMODE_FULL;
232269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    conn_->set_remote_ice_mode(remote_ice_mode);
233269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    conn_->set_use_candidate_attr(remote_ice_mode == ICEMODE_FULL);
234269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    conn_->SignalStateChange.connect(
235269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        this, &TestChannel::OnConnectionStateChange);
236be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    conn_->SignalDestroyed.connect(this, &TestChannel::OnDestroyed);
237b594041ec8a3ae9f501260e2456d9d5ce6482819Guo-wei Shieh    conn_->SignalReadyToSend.connect(this,
238b594041ec8a3ae9f501260e2456d9d5ce6482819Guo-wei Shieh                                     &TestChannel::OnConnectionReadyToSend);
239b594041ec8a3ae9f501260e2456d9d5ce6482819Guo-wei Shieh    connection_ready_to_send_ = false;
240269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
241269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  void OnConnectionStateChange(Connection* conn) {
242269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    if (conn->write_state() == Connection::STATE_WRITABLE) {
243269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      conn->set_use_candidate_attr(true);
244269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      nominated_ = true;
245269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    }
246269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
2471eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  void AcceptConnection(const Candidate& remote_candidate) {
248269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    ASSERT_TRUE(remote_request_.get() != NULL);
2491eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh    Candidate c = remote_candidate;
250269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    c.set_address(remote_address_);
2511eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh    conn_ = port_->CreateConnection(c, Port::ORIGIN_MESSAGE);
252be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    conn_->SignalDestroyed.connect(this, &TestChannel::OnDestroyed);
2531eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh    port_->SendBindingResponse(remote_request_.get(), remote_address_);
254269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    remote_request_.reset();
255269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
256269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  void Ping() {
257269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    Ping(0);
258269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
2590c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  void Ping(uint32_t now) { conn_->Ping(now); }
260269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  void Stop() {
261be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    if (conn_) {
262be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh      conn_->Destroy();
263be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    }
264269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
265269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
266269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  void OnPortComplete(Port* port) {
267269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    complete_count_++;
268269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
269269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  void SetIceMode(IceMode ice_mode) {
270269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    ice_mode_ = ice_mode;
271269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
272269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
273be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh  int SendData(const char* data, size_t len) {
274be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    rtc::PacketOptions options;
275be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    return conn_->Send(data, len, options);
276be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh  }
277be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh
278269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  void OnUnknownAddress(PortInterface* port, const SocketAddress& addr,
279269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                        ProtocolType proto,
280269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                        IceMessage* msg, const std::string& rf,
281269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                        bool /*port_muxed*/) {
2821eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh    ASSERT_EQ(port_.get(), port);
283269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    if (!remote_address_.IsNil()) {
284269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      ASSERT_EQ(remote_address_, addr);
285269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    }
286269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    const cricket::StunUInt32Attribute* priority_attr =
287269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        msg->GetUInt32(STUN_ATTR_PRIORITY);
288269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    const cricket::StunByteStringAttribute* mi_attr =
289269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY);
290269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    const cricket::StunUInt32Attribute* fingerprint_attr =
291269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        msg->GetUInt32(STUN_ATTR_FINGERPRINT);
2927cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher    EXPECT_TRUE(priority_attr != NULL);
2937cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher    EXPECT_TRUE(mi_attr != NULL);
2947cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher    EXPECT_TRUE(fingerprint_attr != NULL);
295269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    remote_address_ = addr;
296269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    remote_request_.reset(CopyStunMessage(msg));
297269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    remote_frag_ = rf;
298269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
299269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
300269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  void OnDestroyed(Connection* conn) {
301269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    ASSERT_EQ(conn_, conn);
302be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    LOG(INFO) << "OnDestroy connection " << conn << " deleted";
303269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    conn_ = NULL;
304be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    // When the connection is destroyed, also clear these fields so future
305be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    // connections are possible.
306be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    remote_request_.reset();
307be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    remote_address_.Clear();
308269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
309269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
310269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  void OnSrcPortDestroyed(PortInterface* port) {
3111eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh    Port* destroyed_src = port_.release();
312269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    ASSERT_EQ(destroyed_src, port);
313269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
314269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
3151eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  Port* port() { return port_.get(); }
316be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh
317269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  bool nominated() const { return nominated_; }
318269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
319b594041ec8a3ae9f501260e2456d9d5ce6482819Guo-wei Shieh  void set_connection_ready_to_send(bool ready) {
320b594041ec8a3ae9f501260e2456d9d5ce6482819Guo-wei Shieh    connection_ready_to_send_ = ready;
321b594041ec8a3ae9f501260e2456d9d5ce6482819Guo-wei Shieh  }
322b594041ec8a3ae9f501260e2456d9d5ce6482819Guo-wei Shieh  bool connection_ready_to_send() const {
323b594041ec8a3ae9f501260e2456d9d5ce6482819Guo-wei Shieh    return connection_ready_to_send_;
324b594041ec8a3ae9f501260e2456d9d5ce6482819Guo-wei Shieh  }
325b594041ec8a3ae9f501260e2456d9d5ce6482819Guo-wei Shieh
326269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org private:
327b594041ec8a3ae9f501260e2456d9d5ce6482819Guo-wei Shieh  // ReadyToSend will only issue after a Connection recovers from EWOULDBLOCK.
328b594041ec8a3ae9f501260e2456d9d5ce6482819Guo-wei Shieh  void OnConnectionReadyToSend(Connection* conn) {
329b594041ec8a3ae9f501260e2456d9d5ce6482819Guo-wei Shieh    ASSERT_EQ(conn, conn_);
330b594041ec8a3ae9f501260e2456d9d5ce6482819Guo-wei Shieh    connection_ready_to_send_ = true;
331b594041ec8a3ae9f501260e2456d9d5ce6482819Guo-wei Shieh  }
332b594041ec8a3ae9f501260e2456d9d5ce6482819Guo-wei Shieh
333269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  IceMode ice_mode_;
3341eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  rtc::scoped_ptr<Port> port_;
335269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
336269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  int complete_count_;
337269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Connection* conn_;
338269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  SocketAddress remote_address_;
339269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<StunMessage> remote_request_;
340269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  std::string remote_frag_;
341269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  bool nominated_;
342b594041ec8a3ae9f501260e2456d9d5ce6482819Guo-wei Shieh  bool connection_ready_to_send_ = false;
343269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org};
344269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
345269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgclass PortTest : public testing::Test, public sigslot::has_slots<> {
346269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org public:
347269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  PortTest()
348269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      : main_(rtc::Thread::Current()),
349269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        pss_(new rtc::PhysicalSocketServer),
350269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        ss_(new rtc::VirtualSocketServer(pss_.get())),
351269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        ss_scope_(ss_.get()),
352269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        network_("unittest", "unittest", rtc::IPAddress(INADDR_ANY), 32),
353269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        socket_factory_(rtc::Thread::Current()),
354c5d0d95fd8957a7a6645b1196e5f1e9cee33525cdeadbeef        nat_factory1_(ss_.get(), kNatAddr1, SocketAddress()),
355c5d0d95fd8957a7a6645b1196e5f1e9cee33525cdeadbeef        nat_factory2_(ss_.get(), kNatAddr2, SocketAddress()),
356269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        nat_socket_factory1_(&nat_factory1_),
357269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        nat_socket_factory2_(&nat_factory2_),
358269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        stun_server_(TestStunServer::Create(main_, kStunAddr)),
359269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        turn_server_(main_, kTurnUdpIntAddr, kTurnUdpExtAddr),
360be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh        relay_server_(main_,
361be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh                      kRelayUdpIntAddr,
362be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh                      kRelayUdpExtAddr,
363be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh                      kRelayTcpIntAddr,
364be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh                      kRelayTcpExtAddr,
365be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh                      kRelaySslTcpIntAddr,
366be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh                      kRelaySslTcpExtAddr),
367269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        username_(rtc::CreateRandomString(ICE_UFRAG_LENGTH)),
368269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        password_(rtc::CreateRandomString(ICE_PWD_LENGTH)),
369269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        role_conflict_(false),
370269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        destroyed_(false) {
371269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    network_.AddIP(rtc::IPAddress(INADDR_ANY));
372269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
373269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
374269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org protected:
375269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  void TestLocalToLocal() {
376269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    Port* port1 = CreateUdpPort(kLocalAddr1);
3777cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher    port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
378269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    Port* port2 = CreateUdpPort(kLocalAddr2);
3797cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher    port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
380269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    TestConnectivity("udp", port1, "udp", port2, true, true, true, true);
381269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
382269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  void TestLocalToStun(NATType ntype) {
383269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    Port* port1 = CreateUdpPort(kLocalAddr1);
3847cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher    port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
385269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    nat_server2_.reset(CreateNatServer(kNatAddr2, ntype));
386269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    Port* port2 = CreateStunPort(kLocalAddr2, &nat_socket_factory2_);
3877cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher    port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
388269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    TestConnectivity("udp", port1, StunName(ntype), port2,
389269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                     ntype == NAT_OPEN_CONE, true,
390269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                     ntype != NAT_SYMMETRIC, true);
391269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
392269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  void TestLocalToRelay(RelayType rtype, ProtocolType proto) {
393269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    Port* port1 = CreateUdpPort(kLocalAddr1);
3947cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher    port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
395269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    Port* port2 = CreateRelayPort(kLocalAddr2, rtype, proto, PROTO_UDP);
3967cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher    port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
397269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    TestConnectivity("udp", port1, RelayName(rtype, proto), port2,
398269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                     rtype == RELAY_GTURN, true, true, true);
399269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
400269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  void TestStunToLocal(NATType ntype) {
401269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    nat_server1_.reset(CreateNatServer(kNatAddr1, ntype));
402269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    Port* port1 = CreateStunPort(kLocalAddr1, &nat_socket_factory1_);
4037cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher    port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
404269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    Port* port2 = CreateUdpPort(kLocalAddr2);
4057cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher    port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
406269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    TestConnectivity(StunName(ntype), port1, "udp", port2,
407269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                     true, ntype != NAT_SYMMETRIC, true, true);
408269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
409269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  void TestStunToStun(NATType ntype1, NATType ntype2) {
410269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    nat_server1_.reset(CreateNatServer(kNatAddr1, ntype1));
411269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    Port* port1 = CreateStunPort(kLocalAddr1, &nat_socket_factory1_);
4127cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher    port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
413269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    nat_server2_.reset(CreateNatServer(kNatAddr2, ntype2));
414269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    Port* port2 = CreateStunPort(kLocalAddr2, &nat_socket_factory2_);
4157cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher    port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
416269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    TestConnectivity(StunName(ntype1), port1, StunName(ntype2), port2,
417269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                     ntype2 == NAT_OPEN_CONE,
418269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                     ntype1 != NAT_SYMMETRIC, ntype2 != NAT_SYMMETRIC,
419269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                     ntype1 + ntype2 < (NAT_PORT_RESTRICTED + NAT_SYMMETRIC));
420269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
421269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  void TestStunToRelay(NATType ntype, RelayType rtype, ProtocolType proto) {
422269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    nat_server1_.reset(CreateNatServer(kNatAddr1, ntype));
423269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    Port* port1 = CreateStunPort(kLocalAddr1, &nat_socket_factory1_);
4247cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher    port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
425269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    Port* port2 = CreateRelayPort(kLocalAddr2, rtype, proto, PROTO_UDP);
4267cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher    port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
427269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    TestConnectivity(StunName(ntype), port1, RelayName(rtype, proto), port2,
428269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                     rtype == RELAY_GTURN, ntype != NAT_SYMMETRIC, true, true);
429269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
430269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  void TestTcpToTcp() {
431269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    Port* port1 = CreateTcpPort(kLocalAddr1);
4327cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher    port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
433269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    Port* port2 = CreateTcpPort(kLocalAddr2);
4347cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher    port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
435269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    TestConnectivity("tcp", port1, "tcp", port2, true, false, true, true);
436269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
437269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  void TestTcpToRelay(RelayType rtype, ProtocolType proto) {
438269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    Port* port1 = CreateTcpPort(kLocalAddr1);
4397cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher    port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
440269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    Port* port2 = CreateRelayPort(kLocalAddr2, rtype, proto, PROTO_TCP);
4417cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher    port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
442269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    TestConnectivity("tcp", port1, RelayName(rtype, proto), port2,
443269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                     rtype == RELAY_GTURN, false, true, true);
444269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
445269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  void TestSslTcpToRelay(RelayType rtype, ProtocolType proto) {
446269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    Port* port1 = CreateTcpPort(kLocalAddr1);
4477cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher    port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
448269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    Port* port2 = CreateRelayPort(kLocalAddr2, rtype, proto, PROTO_SSLTCP);
4497cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher    port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
450269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    TestConnectivity("ssltcp", port1, RelayName(rtype, proto), port2,
451269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                     rtype == RELAY_GTURN, false, true, true);
452269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
453269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // helpers for above functions
454269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  UDPPort* CreateUdpPort(const SocketAddress& addr) {
455269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    return CreateUdpPort(addr, &socket_factory_);
456269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
457269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  UDPPort* CreateUdpPort(const SocketAddress& addr,
458269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                         PacketSocketFactory* socket_factory) {
4597cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher    return UDPPort::Create(main_, socket_factory, &network_,
4607cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher                           addr.ipaddr(), 0, 0, username_, password_,
4617cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher                           std::string(), false);
462269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
463269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TCPPort* CreateTcpPort(const SocketAddress& addr) {
4647cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher    return CreateTcpPort(addr, &socket_factory_);
465269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
466269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TCPPort* CreateTcpPort(const SocketAddress& addr,
467269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                        PacketSocketFactory* socket_factory) {
4687cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher    return TCPPort::Create(main_, socket_factory, &network_,
4697cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher                           addr.ipaddr(), 0, 0, username_, password_,
4707cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher                           true);
471269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
472269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  StunPort* CreateStunPort(const SocketAddress& addr,
473269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                           rtc::PacketSocketFactory* factory) {
474269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    ServerAddresses stun_servers;
475269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    stun_servers.insert(kStunAddr);
4767cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher    return StunPort::Create(main_, factory, &network_,
4777cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher                            addr.ipaddr(), 0, 0,
4787cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher                            username_, password_, stun_servers,
4797cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher                            std::string());
480269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
481269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Port* CreateRelayPort(const SocketAddress& addr, RelayType rtype,
482269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                        ProtocolType int_proto, ProtocolType ext_proto) {
483269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    if (rtype == RELAY_TURN) {
484269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      return CreateTurnPort(addr, &socket_factory_, int_proto, ext_proto);
485269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    } else {
486269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      return CreateGturnPort(addr, int_proto, ext_proto);
487269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    }
488269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
489269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TurnPort* CreateTurnPort(const SocketAddress& addr,
490269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                           PacketSocketFactory* socket_factory,
491269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                           ProtocolType int_proto, ProtocolType ext_proto) {
492269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    return CreateTurnPort(addr, socket_factory,
493269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                          int_proto, ext_proto, kTurnUdpIntAddr);
494269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
495269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TurnPort* CreateTurnPort(const SocketAddress& addr,
496269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                           PacketSocketFactory* socket_factory,
497269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                           ProtocolType int_proto, ProtocolType ext_proto,
498269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                           const rtc::SocketAddress& server_addr) {
4997cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher    return TurnPort::Create(main_, socket_factory, &network_,
5007cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher                            addr.ipaddr(), 0, 0,
5017cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher                            username_, password_, ProtocolAddress(
5027cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher                                server_addr, PROTO_UDP),
5037cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher                            kRelayCredentials, 0,
5047cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher                            std::string());
505269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
506269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  RelayPort* CreateGturnPort(const SocketAddress& addr,
507269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                             ProtocolType int_proto, ProtocolType ext_proto) {
508269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    RelayPort* port = CreateGturnPort(addr);
509269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    SocketAddress addrs[] =
510269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        { kRelayUdpIntAddr, kRelayTcpIntAddr, kRelaySslTcpIntAddr };
511269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    port->AddServerAddress(ProtocolAddress(addrs[int_proto], int_proto));
512269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    return port;
513269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
514269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  RelayPort* CreateGturnPort(const SocketAddress& addr) {
5157cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher    // TODO(pthatcher):  Remove GTURN.
5167cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher    return RelayPort::Create(main_, &socket_factory_, &network_,
5177cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher                             addr.ipaddr(), 0, 0,
5187cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher                             username_, password_);
519269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    // TODO: Add an external address for ext_proto, so that the
520269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    // other side can connect to this port using a non-UDP protocol.
521269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
522269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::NATServer* CreateNatServer(const SocketAddress& addr,
523269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                        rtc::NATType type) {
524c5d0d95fd8957a7a6645b1196e5f1e9cee33525cdeadbeef    return new rtc::NATServer(type, ss_.get(), addr, addr, ss_.get(), addr);
525269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
526269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  static const char* StunName(NATType type) {
527269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    switch (type) {
528269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      case NAT_OPEN_CONE:       return "stun(open cone)";
529269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      case NAT_ADDR_RESTRICTED: return "stun(addr restricted)";
530269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      case NAT_PORT_RESTRICTED: return "stun(port restricted)";
531269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      case NAT_SYMMETRIC:       return "stun(symmetric)";
532269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      default:                  return "stun(?)";
533269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    }
534269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
535269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  static const char* RelayName(RelayType type, ProtocolType proto) {
536269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    if (type == RELAY_TURN) {
537269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      switch (proto) {
538269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        case PROTO_UDP:           return "turn(udp)";
539269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        case PROTO_TCP:           return "turn(tcp)";
540269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        case PROTO_SSLTCP:        return "turn(ssltcp)";
541269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        default:                  return "turn(?)";
542269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      }
543269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    } else {
544269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      switch (proto) {
545269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        case PROTO_UDP:           return "gturn(udp)";
546269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        case PROTO_TCP:           return "gturn(tcp)";
547269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        case PROTO_SSLTCP:        return "gturn(ssltcp)";
548269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        default:                  return "gturn(?)";
549269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      }
550269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    }
551269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
552269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
553269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  void TestCrossFamilyPorts(int type);
554269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
555b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher  void ExpectPortsCanConnect(bool can_connect, Port* p1, Port* p2);
556b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher
557269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // This does all the work and then deletes |port1| and |port2|.
558269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  void TestConnectivity(const char* name1, Port* port1,
559269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                        const char* name2, Port* port2,
560269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                        bool accept, bool same_addr1,
561269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                        bool same_addr2, bool possible);
562269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
563be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh  // This connects the provided channels which have already started.  |ch1|
564be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh  // should have its Connection created (either through CreateConnection() or
565be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh  // TCP reconnecting mechanism before entering this function.
566be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh  void ConnectStartedChannels(TestChannel* ch1, TestChannel* ch2) {
567be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    ASSERT_TRUE(ch1->conn());
568be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    EXPECT_TRUE_WAIT(ch1->conn()->connected(), kTimeout);  // for TCP connect
569be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    ch1->Ping();
570be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    WAIT(!ch2->remote_address().IsNil(), kTimeout);
571be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh
572be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    // Send a ping from dst to src.
5731eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh    ch2->AcceptConnection(GetCandidate(ch1->port()));
574be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    ch2->Ping();
575be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch2->conn()->write_state(),
576be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh                   kTimeout);
577be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh  }
578be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh
579269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // This connects and disconnects the provided channels in the same sequence as
580269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // TestConnectivity with all options set to |true|.  It does not delete either
581269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // channel.
582be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh  void StartConnectAndStopChannels(TestChannel* ch1, TestChannel* ch2) {
583be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    // Acquire addresses.
584be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    ch1->Start();
585be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    ch2->Start();
586be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh
5871eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh    ch1->CreateConnection(GetCandidate(ch2->port()));
588be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    ConnectStartedChannels(ch1, ch2);
589be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh
590be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    // Destroy the connections.
591be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    ch1->Stop();
592be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    ch2->Stop();
593be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh  }
594be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh
595be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh  // This disconnects both end's Connection and make sure ch2 ready for new
596be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh  // connection.
597be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh  void DisconnectTcpTestChannels(TestChannel* ch1, TestChannel* ch2) {
5981eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh    TCPConnection* tcp_conn1 = static_cast<TCPConnection*>(ch1->conn());
5991eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh    TCPConnection* tcp_conn2 = static_cast<TCPConnection*>(ch2->conn());
6001eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh    ASSERT_TRUE(
6011eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh        ss_->CloseTcpConnections(tcp_conn1->socket()->GetLocalAddress(),
6021eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh                                 tcp_conn2->socket()->GetLocalAddress()));
603be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh
604be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    // Wait for both OnClose are delivered.
605be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    EXPECT_TRUE_WAIT(!ch1->conn()->connected(), kTimeout);
606be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    EXPECT_TRUE_WAIT(!ch2->conn()->connected(), kTimeout);
607be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh
6081eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh    // Ensure redundant SignalClose events on TcpConnection won't break tcp
6091eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh    // reconnection. Chromium will fire SignalClose for all outstanding IPC
6101eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh    // packets during reconnection.
6111eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh    tcp_conn1->socket()->SignalClose(tcp_conn1->socket(), 0);
6121eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh    tcp_conn2->socket()->SignalClose(tcp_conn2->socket(), 0);
6131eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh
6141eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh    // Speed up destroying ch2's connection such that the test is ready to
6151eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh    // accept a new connection from ch1 before ch1's connection destroys itself.
616be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    ch2->conn()->Destroy();
617be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    EXPECT_TRUE_WAIT(ch2->conn() == NULL, kTimeout);
618be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh  }
619be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh
620be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh  void TestTcpReconnect(bool ping_after_disconnected,
621be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh                        bool send_after_disconnected) {
622be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    Port* port1 = CreateTcpPort(kLocalAddr1);
6237cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher    port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
624be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    Port* port2 = CreateTcpPort(kLocalAddr2);
6257cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher    port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
626be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh
627be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    port1->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
628be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    port2->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
629be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh
630be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    // Set up channels and ensure both ports will be deleted.
6311eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh    TestChannel ch1(port1);
6321eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh    TestChannel ch2(port2);
633be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    EXPECT_EQ(0, ch1.complete_count());
634be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    EXPECT_EQ(0, ch2.complete_count());
635be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh
636be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    ch1.Start();
637be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    ch2.Start();
638be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    ASSERT_EQ_WAIT(1, ch1.complete_count(), kTimeout);
639be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    ASSERT_EQ_WAIT(1, ch2.complete_count(), kTimeout);
640be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh
641be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    // Initial connecting the channel, create connection on channel1.
6421eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh    ch1.CreateConnection(GetCandidate(port2));
643be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    ConnectStartedChannels(&ch1, &ch2);
644be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh
645be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    // Shorten the timeout period.
646be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    const int kTcpReconnectTimeout = kTimeout;
647be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    static_cast<TCPConnection*>(ch1.conn())
648be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh        ->set_reconnection_timeout(kTcpReconnectTimeout);
649be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    static_cast<TCPConnection*>(ch2.conn())
650be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh        ->set_reconnection_timeout(kTcpReconnectTimeout);
651be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh
652b594041ec8a3ae9f501260e2456d9d5ce6482819Guo-wei Shieh    EXPECT_FALSE(ch1.connection_ready_to_send());
653b594041ec8a3ae9f501260e2456d9d5ce6482819Guo-wei Shieh    EXPECT_FALSE(ch2.connection_ready_to_send());
654b594041ec8a3ae9f501260e2456d9d5ce6482819Guo-wei Shieh
655be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    // Once connected, disconnect them.
656be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    DisconnectTcpTestChannels(&ch1, &ch2);
657be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh
658be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    if (send_after_disconnected || ping_after_disconnected) {
659be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh      if (send_after_disconnected) {
660be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh        // First SendData after disconnect should fail but will trigger
661be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh        // reconnect.
662be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh        EXPECT_EQ(-1, ch1.SendData(data, static_cast<int>(strlen(data))));
663be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh      }
664be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh
665be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh      if (ping_after_disconnected) {
666be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh        // Ping should trigger reconnect.
667be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh        ch1.Ping();
668be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh      }
669be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh
670be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh      // Wait for channel's outgoing TCPConnection connected.
671be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh      EXPECT_TRUE_WAIT(ch1.conn()->connected(), kTimeout);
672be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh
673be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh      // Verify that we could still connect channels.
674be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh      ConnectStartedChannels(&ch1, &ch2);
675b594041ec8a3ae9f501260e2456d9d5ce6482819Guo-wei Shieh      EXPECT_TRUE_WAIT(ch1.connection_ready_to_send(),
676b594041ec8a3ae9f501260e2456d9d5ce6482819Guo-wei Shieh                       kTcpReconnectTimeout);
677b594041ec8a3ae9f501260e2456d9d5ce6482819Guo-wei Shieh      // Channel2 is the passive one so a new connection is created during
678b594041ec8a3ae9f501260e2456d9d5ce6482819Guo-wei Shieh      // reconnect. This new connection should never have issued EWOULDBLOCK
679b594041ec8a3ae9f501260e2456d9d5ce6482819Guo-wei Shieh      // hence the connection_ready_to_send() should be false.
680b594041ec8a3ae9f501260e2456d9d5ce6482819Guo-wei Shieh      EXPECT_FALSE(ch2.connection_ready_to_send());
681be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    } else {
682be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh      EXPECT_EQ(ch1.conn()->write_state(), Connection::STATE_WRITABLE);
6831eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh      // Since the reconnection never happens, the connections should have been
6841eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh      // destroyed after the timeout.
6851eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh      EXPECT_TRUE_WAIT(!ch1.conn(), kTcpReconnectTimeout + kTimeout);
6861eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh      EXPECT_TRUE(!ch2.conn());
687be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    }
688be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh
689be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    // Tear down and ensure that goes smoothly.
690be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    ch1.Stop();
691be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    ch2.Stop();
692be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    EXPECT_TRUE_WAIT(ch1.conn() == NULL, kTimeout);
693be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh    EXPECT_TRUE_WAIT(ch2.conn() == NULL, kTimeout);
694be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh  }
695269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
696269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  IceMessage* CreateStunMessage(int type) {
697269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    IceMessage* msg = new IceMessage();
698269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    msg->SetType(type);
699269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    msg->SetTransactionID("TESTTESTTEST");
700269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    return msg;
701269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
702269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  IceMessage* CreateStunMessageWithUsername(int type,
703269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                            const std::string& username) {
704269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    IceMessage* msg = CreateStunMessage(type);
705269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    msg->AddAttribute(
706269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        new StunByteStringAttribute(STUN_ATTR_USERNAME, username));
707269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    return msg;
708269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
709269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestPort* CreateTestPort(const rtc::SocketAddress& addr,
710269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                           const std::string& username,
711269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                           const std::string& password) {
712269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    TestPort* port =  new TestPort(main_, "test", &socket_factory_, &network_,
713269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                   addr.ipaddr(), 0, 0, username, password);
714269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    port->SignalRoleConflict.connect(this, &PortTest::OnRoleConflict);
715269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    return port;
716269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
717269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestPort* CreateTestPort(const rtc::SocketAddress& addr,
718269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                           const std::string& username,
719269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                           const std::string& password,
720269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                           cricket::IceRole role,
721269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                           int tiebreaker) {
722269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    TestPort* port = CreateTestPort(addr, username, password);
723269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    port->SetIceRole(role);
724269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    port->SetIceTiebreaker(tiebreaker);
725269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    return port;
726269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
727269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
728269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  void OnRoleConflict(PortInterface* port) {
729269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    role_conflict_ = true;
730269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
731269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  bool role_conflict() const { return role_conflict_; }
732269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
733269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  void ConnectToSignalDestroyed(PortInterface* port) {
734269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    port->SignalDestroyed.connect(this, &PortTest::OnDestroyed);
735269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
736269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
737269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  void OnDestroyed(PortInterface* port) {
738269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    destroyed_ = true;
739269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
740269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  bool destroyed() const { return destroyed_; }
741269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
742269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::BasicPacketSocketFactory* nat_socket_factory1() {
743269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    return &nat_socket_factory1_;
744269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
745269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
7461eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh protected:
7471eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  rtc::VirtualSocketServer* vss() { return ss_.get(); }
7481eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh
749269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org private:
750269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::Thread* main_;
751269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<rtc::PhysicalSocketServer> pss_;
752269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<rtc::VirtualSocketServer> ss_;
753269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::SocketServerScope ss_scope_;
754269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::Network network_;
755269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::BasicPacketSocketFactory socket_factory_;
756269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<rtc::NATServer> nat_server1_;
757269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<rtc::NATServer> nat_server2_;
758269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::NATSocketFactory nat_factory1_;
759269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::NATSocketFactory nat_factory2_;
760269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::BasicPacketSocketFactory nat_socket_factory1_;
761269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::BasicPacketSocketFactory nat_socket_factory2_;
762269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  scoped_ptr<TestStunServer> stun_server_;
763269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestTurnServer turn_server_;
764269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestRelayServer relay_server_;
765269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  std::string username_;
766269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  std::string password_;
767269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  bool role_conflict_;
768269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  bool destroyed_;
769269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org};
770269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
771269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgvoid PortTest::TestConnectivity(const char* name1, Port* port1,
772269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                const char* name2, Port* port2,
773269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                bool accept, bool same_addr1,
774269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                bool same_addr2, bool possible) {
775269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  LOG(LS_INFO) << "Test: " << name1 << " to " << name2 << ": ";
776269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  port1->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
777269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  port2->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
778269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
779269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Set up channels and ensure both ports will be deleted.
7801eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  TestChannel ch1(port1);
7811eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  TestChannel ch2(port2);
782269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(0, ch1.complete_count());
783269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(0, ch2.complete_count());
784269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
785269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Acquire addresses.
786269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ch1.Start();
787269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ch2.Start();
788269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_EQ_WAIT(1, ch1.complete_count(), kTimeout);
789269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_EQ_WAIT(1, ch2.complete_count(), kTimeout);
790269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
791269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Send a ping from src to dst. This may or may not make it.
7921eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  ch1.CreateConnection(GetCandidate(port2));
793269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(ch1.conn() != NULL);
794269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE_WAIT(ch1.conn()->connected(), kTimeout);  // for TCP connect
795269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ch1.Ping();
796269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  WAIT(!ch2.remote_address().IsNil(), kTimeout);
797269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
798269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  if (accept) {
799269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    // We are able to send a ping from src to dst. This is the case when
800269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    // sending to UDP ports and cone NATs.
801269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    EXPECT_TRUE(ch1.remote_address().IsNil());
802269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    EXPECT_EQ(ch2.remote_fragment(), port1->username_fragment());
803269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
804269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    // Ensure the ping came from the same address used for src.
805269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    // This is the case unless the source NAT was symmetric.
806269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    if (same_addr1) EXPECT_EQ(ch2.remote_address(), GetAddress(port1));
807269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    EXPECT_TRUE(same_addr2);
808269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
809269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    // Send a ping from dst to src.
8101eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh    ch2.AcceptConnection(GetCandidate(port1));
811269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    ASSERT_TRUE(ch2.conn() != NULL);
812269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    ch2.Ping();
813269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch2.conn()->write_state(),
814269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                   kTimeout);
815269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  } else {
816269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    // We can't send a ping from src to dst, so flip it around. This will happen
817269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    // when the destination NAT is addr/port restricted or symmetric.
818269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    EXPECT_TRUE(ch1.remote_address().IsNil());
819269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    EXPECT_TRUE(ch2.remote_address().IsNil());
820269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
821269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    // Send a ping from dst to src. Again, this may or may not make it.
8221eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh    ch2.CreateConnection(GetCandidate(port1));
823269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    ASSERT_TRUE(ch2.conn() != NULL);
824269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    ch2.Ping();
825269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    WAIT(ch2.conn()->write_state() == Connection::STATE_WRITABLE, kTimeout);
826269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
827269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    if (same_addr1 && same_addr2) {
828269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      // The new ping got back to the source.
82904ac81f2fd8ef6680522438fac1894db5415a0ecPeter Thatcher      EXPECT_TRUE(ch1.conn()->receiving());
830269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      EXPECT_EQ(Connection::STATE_WRITABLE, ch2.conn()->write_state());
831269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
832269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      // First connection may not be writable if the first ping did not get
833269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      // through.  So we will have to do another.
834269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      if (ch1.conn()->write_state() == Connection::STATE_WRITE_INIT) {
835269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        ch1.Ping();
836269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch1.conn()->write_state(),
837269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                       kTimeout);
838269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      }
839269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    } else if (!same_addr1 && possible) {
840269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      // The new ping went to the candidate address, but that address was bad.
841269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      // This will happen when the source NAT is symmetric.
842269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      EXPECT_TRUE(ch1.remote_address().IsNil());
843269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      EXPECT_TRUE(ch2.remote_address().IsNil());
844269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
845269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      // However, since we have now sent a ping to the source IP, we should be
846269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      // able to get a ping from it. This gives us the real source address.
847269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      ch1.Ping();
848269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      EXPECT_TRUE_WAIT(!ch2.remote_address().IsNil(), kTimeout);
84904ac81f2fd8ef6680522438fac1894db5415a0ecPeter Thatcher      EXPECT_FALSE(ch2.conn()->receiving());
850269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      EXPECT_TRUE(ch1.remote_address().IsNil());
851269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
852269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      // Pick up the actual address and establish the connection.
8531eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh      ch2.AcceptConnection(GetCandidate(port1));
854269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      ASSERT_TRUE(ch2.conn() != NULL);
855269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      ch2.Ping();
856269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch2.conn()->write_state(),
857269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                     kTimeout);
858269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    } else if (!same_addr2 && possible) {
859269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      // The new ping came in, but from an unexpected address. This will happen
860269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      // when the destination NAT is symmetric.
861269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      EXPECT_FALSE(ch1.remote_address().IsNil());
86204ac81f2fd8ef6680522438fac1894db5415a0ecPeter Thatcher      EXPECT_FALSE(ch1.conn()->receiving());
863269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
864269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      // Update our address and complete the connection.
8651eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh      ch1.AcceptConnection(GetCandidate(port2));
866269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      ch1.Ping();
867269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch1.conn()->write_state(),
868269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                     kTimeout);
869269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    } else {  // (!possible)
870269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      // There should be s no way for the pings to reach each other. Check it.
871269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      EXPECT_TRUE(ch1.remote_address().IsNil());
872269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      EXPECT_TRUE(ch2.remote_address().IsNil());
873269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      ch1.Ping();
874269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      WAIT(!ch2.remote_address().IsNil(), kTimeout);
875269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      EXPECT_TRUE(ch1.remote_address().IsNil());
876269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      EXPECT_TRUE(ch2.remote_address().IsNil());
877269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    }
878269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
879269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
880269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Everything should be good, unless we know the situation is impossible.
881269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(ch1.conn() != NULL);
882269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(ch2.conn() != NULL);
883269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  if (possible) {
88404ac81f2fd8ef6680522438fac1894db5415a0ecPeter Thatcher    EXPECT_TRUE(ch1.conn()->receiving());
885269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    EXPECT_EQ(Connection::STATE_WRITABLE, ch1.conn()->write_state());
88604ac81f2fd8ef6680522438fac1894db5415a0ecPeter Thatcher    EXPECT_TRUE(ch2.conn()->receiving());
887269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    EXPECT_EQ(Connection::STATE_WRITABLE, ch2.conn()->write_state());
888269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  } else {
88904ac81f2fd8ef6680522438fac1894db5415a0ecPeter Thatcher    EXPECT_FALSE(ch1.conn()->receiving());
890269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    EXPECT_NE(Connection::STATE_WRITABLE, ch1.conn()->write_state());
89104ac81f2fd8ef6680522438fac1894db5415a0ecPeter Thatcher    EXPECT_FALSE(ch2.conn()->receiving());
892269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    EXPECT_NE(Connection::STATE_WRITABLE, ch2.conn()->write_state());
893269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
894269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
895269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Tear down and ensure that goes smoothly.
896269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ch1.Stop();
897269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ch2.Stop();
898269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE_WAIT(ch1.conn() == NULL, kTimeout);
899269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE_WAIT(ch2.conn() == NULL, kTimeout);
900269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
901269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
902269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgclass FakePacketSocketFactory : public rtc::PacketSocketFactory {
903269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org public:
904269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  FakePacketSocketFactory()
905269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      : next_udp_socket_(NULL),
906269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        next_server_tcp_socket_(NULL),
907269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org        next_client_tcp_socket_(NULL) {
908269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
909332331fb01f8a316ac6d61cf4572478610fb3472pkasting@chromium.org  ~FakePacketSocketFactory() override { }
910269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
911332331fb01f8a316ac6d61cf4572478610fb3472pkasting@chromium.org  AsyncPacketSocket* CreateUdpSocket(const SocketAddress& address,
9120c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                                     uint16_t min_port,
9130c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                                     uint16_t max_port) override {
914269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    EXPECT_TRUE(next_udp_socket_ != NULL);
915269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    AsyncPacketSocket* result = next_udp_socket_;
916269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    next_udp_socket_ = NULL;
917269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    return result;
918269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
919269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
920332331fb01f8a316ac6d61cf4572478610fb3472pkasting@chromium.org  AsyncPacketSocket* CreateServerTcpSocket(const SocketAddress& local_address,
9210c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                                           uint16_t min_port,
9220c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström                                           uint16_t max_port,
923332331fb01f8a316ac6d61cf4572478610fb3472pkasting@chromium.org                                           int opts) override {
924269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    EXPECT_TRUE(next_server_tcp_socket_ != NULL);
925269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    AsyncPacketSocket* result = next_server_tcp_socket_;
926269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    next_server_tcp_socket_ = NULL;
927269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    return result;
928269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
929269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
930269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // TODO: |proxy_info| and |user_agent| should be set
931269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // per-factory and not when socket is created.
932332331fb01f8a316ac6d61cf4572478610fb3472pkasting@chromium.org  AsyncPacketSocket* CreateClientTcpSocket(const SocketAddress& local_address,
933332331fb01f8a316ac6d61cf4572478610fb3472pkasting@chromium.org                                           const SocketAddress& remote_address,
934332331fb01f8a316ac6d61cf4572478610fb3472pkasting@chromium.org                                           const rtc::ProxyInfo& proxy_info,
935332331fb01f8a316ac6d61cf4572478610fb3472pkasting@chromium.org                                           const std::string& user_agent,
936332331fb01f8a316ac6d61cf4572478610fb3472pkasting@chromium.org                                           int opts) override {
937269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    EXPECT_TRUE(next_client_tcp_socket_ != NULL);
938269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    AsyncPacketSocket* result = next_client_tcp_socket_;
939269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    next_client_tcp_socket_ = NULL;
940269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    return result;
941269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
942269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
943269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  void set_next_udp_socket(AsyncPacketSocket* next_udp_socket) {
944269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    next_udp_socket_ = next_udp_socket;
945269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
946269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  void set_next_server_tcp_socket(AsyncPacketSocket* next_server_tcp_socket) {
947269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    next_server_tcp_socket_ = next_server_tcp_socket;
948269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
949269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  void set_next_client_tcp_socket(AsyncPacketSocket* next_client_tcp_socket) {
950269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    next_client_tcp_socket_ = next_client_tcp_socket;
951269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
952269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::AsyncResolverInterface* CreateAsyncResolver() {
953269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    return NULL;
954269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
955269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
956269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org private:
957269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  AsyncPacketSocket* next_udp_socket_;
958269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  AsyncPacketSocket* next_server_tcp_socket_;
959269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  AsyncPacketSocket* next_client_tcp_socket_;
960269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org};
961269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
962269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgclass FakeAsyncPacketSocket : public AsyncPacketSocket {
963269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org public:
964269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Returns current local address. Address may be set to NULL if the
965269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // socket is not bound yet (GetState() returns STATE_BINDING).
966269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  virtual SocketAddress GetLocalAddress() const {
967269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    return SocketAddress();
968269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
969269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
970269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Returns remote address. Returns zeroes if this is not a client TCP socket.
971269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  virtual SocketAddress GetRemoteAddress() const {
972269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    return SocketAddress();
973269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
974269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
975269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Send a packet.
976269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  virtual int Send(const void *pv, size_t cb,
977269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                   const rtc::PacketOptions& options) {
978269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    return static_cast<int>(cb);
979269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
980269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  virtual int SendTo(const void *pv, size_t cb, const SocketAddress& addr,
981269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                     const rtc::PacketOptions& options) {
982269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    return static_cast<int>(cb);
983269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
984269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  virtual int Close() {
985269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    return 0;
986269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
987269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
988269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  virtual State GetState() const { return state_; }
989269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  virtual int GetOption(Socket::Option opt, int* value) { return 0; }
990269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  virtual int SetOption(Socket::Option opt, int value) { return 0; }
991269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  virtual int GetError() const { return 0; }
992269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  virtual void SetError(int error) { }
993269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
994269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  void set_state(State state) { state_ = state; }
995269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
996269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org private:
997269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  State state_;
998269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org};
999269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1000269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// Local -> XXXX
1001269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestLocalToLocal) {
1002269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestLocalToLocal();
1003269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1004269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1005269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestLocalToConeNat) {
1006269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestLocalToStun(NAT_OPEN_CONE);
1007269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1008269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1009269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestLocalToARNat) {
1010269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestLocalToStun(NAT_ADDR_RESTRICTED);
1011269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1012269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1013269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestLocalToPRNat) {
1014269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestLocalToStun(NAT_PORT_RESTRICTED);
1015269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1016269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1017269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestLocalToSymNat) {
1018269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestLocalToStun(NAT_SYMMETRIC);
1019269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1020269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1021269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// Flaky: https://code.google.com/p/webrtc/issues/detail?id=3316.
1022269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, DISABLED_TestLocalToTurn) {
1023269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestLocalToRelay(RELAY_TURN, PROTO_UDP);
1024269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1025269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1026269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestLocalToGturn) {
1027269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestLocalToRelay(RELAY_GTURN, PROTO_UDP);
1028269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1029269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1030269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestLocalToTcpGturn) {
1031269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestLocalToRelay(RELAY_GTURN, PROTO_TCP);
1032269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1033269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1034269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestLocalToSslTcpGturn) {
1035269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestLocalToRelay(RELAY_GTURN, PROTO_SSLTCP);
1036269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1037269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1038269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// Cone NAT -> XXXX
1039269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestConeNatToLocal) {
1040269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestStunToLocal(NAT_OPEN_CONE);
1041269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1042269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1043269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestConeNatToConeNat) {
1044269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestStunToStun(NAT_OPEN_CONE, NAT_OPEN_CONE);
1045269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1046269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1047269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestConeNatToARNat) {
1048269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestStunToStun(NAT_OPEN_CONE, NAT_ADDR_RESTRICTED);
1049269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1050269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1051269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestConeNatToPRNat) {
1052269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestStunToStun(NAT_OPEN_CONE, NAT_PORT_RESTRICTED);
1053269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1054269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1055269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestConeNatToSymNat) {
1056269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestStunToStun(NAT_OPEN_CONE, NAT_SYMMETRIC);
1057269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1058269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1059269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestConeNatToTurn) {
1060269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestStunToRelay(NAT_OPEN_CONE, RELAY_TURN, PROTO_UDP);
1061269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1062269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1063269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestConeNatToGturn) {
1064269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestStunToRelay(NAT_OPEN_CONE, RELAY_GTURN, PROTO_UDP);
1065269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1066269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1067269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestConeNatToTcpGturn) {
1068269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestStunToRelay(NAT_OPEN_CONE, RELAY_GTURN, PROTO_TCP);
1069269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1070269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1071269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// Address-restricted NAT -> XXXX
1072269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestARNatToLocal) {
1073269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestStunToLocal(NAT_ADDR_RESTRICTED);
1074269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1075269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1076269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestARNatToConeNat) {
1077269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestStunToStun(NAT_ADDR_RESTRICTED, NAT_OPEN_CONE);
1078269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1079269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1080269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestARNatToARNat) {
1081269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestStunToStun(NAT_ADDR_RESTRICTED, NAT_ADDR_RESTRICTED);
1082269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1083269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1084269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestARNatToPRNat) {
1085269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestStunToStun(NAT_ADDR_RESTRICTED, NAT_PORT_RESTRICTED);
1086269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1087269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1088269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestARNatToSymNat) {
1089269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestStunToStun(NAT_ADDR_RESTRICTED, NAT_SYMMETRIC);
1090269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1091269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1092269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestARNatToTurn) {
1093269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestStunToRelay(NAT_ADDR_RESTRICTED, RELAY_TURN, PROTO_UDP);
1094269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1095269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1096269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestARNatToGturn) {
1097269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestStunToRelay(NAT_ADDR_RESTRICTED, RELAY_GTURN, PROTO_UDP);
1098269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1099269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1100269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestARNATNatToTcpGturn) {
1101269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestStunToRelay(NAT_ADDR_RESTRICTED, RELAY_GTURN, PROTO_TCP);
1102269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1103269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1104269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// Port-restricted NAT -> XXXX
1105269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestPRNatToLocal) {
1106269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestStunToLocal(NAT_PORT_RESTRICTED);
1107269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1108269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1109269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestPRNatToConeNat) {
1110269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestStunToStun(NAT_PORT_RESTRICTED, NAT_OPEN_CONE);
1111269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1112269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1113269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestPRNatToARNat) {
1114269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestStunToStun(NAT_PORT_RESTRICTED, NAT_ADDR_RESTRICTED);
1115269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1116269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1117269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestPRNatToPRNat) {
1118269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestStunToStun(NAT_PORT_RESTRICTED, NAT_PORT_RESTRICTED);
1119269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1120269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1121269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestPRNatToSymNat) {
1122269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Will "fail"
1123269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestStunToStun(NAT_PORT_RESTRICTED, NAT_SYMMETRIC);
1124269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1125269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1126269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestPRNatToTurn) {
1127269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestStunToRelay(NAT_PORT_RESTRICTED, RELAY_TURN, PROTO_UDP);
1128269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1129269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1130269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestPRNatToGturn) {
1131269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestStunToRelay(NAT_PORT_RESTRICTED, RELAY_GTURN, PROTO_UDP);
1132269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1133269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1134269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestPRNatToTcpGturn) {
1135269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestStunToRelay(NAT_PORT_RESTRICTED, RELAY_GTURN, PROTO_TCP);
1136269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1137269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1138269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// Symmetric NAT -> XXXX
1139269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestSymNatToLocal) {
1140269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestStunToLocal(NAT_SYMMETRIC);
1141269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1142269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1143269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestSymNatToConeNat) {
1144269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestStunToStun(NAT_SYMMETRIC, NAT_OPEN_CONE);
1145269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1146269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1147269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestSymNatToARNat) {
1148269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestStunToStun(NAT_SYMMETRIC, NAT_ADDR_RESTRICTED);
1149269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1150269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1151269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestSymNatToPRNat) {
1152269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Will "fail"
1153269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestStunToStun(NAT_SYMMETRIC, NAT_PORT_RESTRICTED);
1154269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1155269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1156269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestSymNatToSymNat) {
1157269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Will "fail"
1158269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestStunToStun(NAT_SYMMETRIC, NAT_SYMMETRIC);
1159269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1160269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1161269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestSymNatToTurn) {
1162269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestStunToRelay(NAT_SYMMETRIC, RELAY_TURN, PROTO_UDP);
1163269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1164269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1165269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestSymNatToGturn) {
1166269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestStunToRelay(NAT_SYMMETRIC, RELAY_GTURN, PROTO_UDP);
1167269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1168269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1169269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestSymNatToTcpGturn) {
1170269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestStunToRelay(NAT_SYMMETRIC, RELAY_GTURN, PROTO_TCP);
1171269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1172269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1173269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// Outbound TCP -> XXXX
1174269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestTcpToTcp) {
1175269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestTcpToTcp();
1176269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1177269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1178be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei ShiehTEST_F(PortTest, TestTcpReconnectOnSendPacket) {
1179be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh  TestTcpReconnect(false /* ping */, true /* send */);
1180be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh}
1181be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh
1182be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei ShiehTEST_F(PortTest, TestTcpReconnectOnPing) {
1183be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh  TestTcpReconnect(true /* ping */, false /* send */);
1184be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh}
1185be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh
1186be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei ShiehTEST_F(PortTest, TestTcpReconnectTimeout) {
1187be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh  TestTcpReconnect(false /* ping */, false /* send */);
1188be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh}
1189be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh
11901eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh// Test when TcpConnection never connects, the OnClose() will be called to
11911eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh// destroy the connection.
11921eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei ShiehTEST_F(PortTest, TestTcpNeverConnect) {
11931eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  Port* port1 = CreateTcpPort(kLocalAddr1);
11941eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
11951eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  port1->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
11961eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh
11971eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  // Set up a channel and ensure the port will be deleted.
11981eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  TestChannel ch1(port1);
11991eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  EXPECT_EQ(0, ch1.complete_count());
12001eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh
12011eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  ch1.Start();
12021eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  ASSERT_EQ_WAIT(1, ch1.complete_count(), kTimeout);
12031eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh
12041eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  rtc::scoped_ptr<rtc::AsyncSocket> server(
12051eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh      vss()->CreateAsyncSocket(kLocalAddr2.family(), SOCK_STREAM));
12061eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  // Bind but not listen.
12071eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  EXPECT_EQ(0, server->Bind(kLocalAddr2));
12081eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh
12091eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  Candidate c = GetCandidate(port1);
12101eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  c.set_address(server->GetLocalAddress());
12111eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh
12121eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  ch1.CreateConnection(c);
12131eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  EXPECT_TRUE(ch1.conn());
12141eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  EXPECT_TRUE_WAIT(!ch1.conn(), kTimeout);  // for TCP connect
12151eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh}
12161eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh
1217269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org/* TODO: Enable these once testrelayserver can accept external TCP.
1218269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestTcpToTcpRelay) {
1219269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestTcpToRelay(PROTO_TCP);
1220269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1221269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1222269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestTcpToSslTcpRelay) {
1223269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestTcpToRelay(PROTO_SSLTCP);
1224269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1225269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org*/
1226269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1227269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// Outbound SSLTCP -> XXXX
1228269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org/* TODO: Enable these once testrelayserver can accept external SSL.
1229269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestSslTcpToTcpRelay) {
1230269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestSslTcpToRelay(PROTO_TCP);
1231269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1232269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1233269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestSslTcpToSslTcpRelay) {
1234269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestSslTcpToRelay(PROTO_SSLTCP);
1235269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1236269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org*/
1237269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1238269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// This test case verifies standard ICE features in STUN messages. Currently it
1239269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// verifies Message Integrity attribute in STUN messages and username in STUN
1240269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// binding request will have colon (":") between remote and local username.
12417cbd188c5ed7df80bb737bd4ada94422730e2d89Peter ThatcherTEST_F(PortTest, TestLocalToLocalStandard) {
1242269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  UDPPort* port1 = CreateUdpPort(kLocalAddr1);
1243269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
1244269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  port1->SetIceTiebreaker(kTiebreaker1);
1245269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  UDPPort* port2 = CreateUdpPort(kLocalAddr2);
1246269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
1247269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  port2->SetIceTiebreaker(kTiebreaker2);
1248269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Same parameters as TestLocalToLocal above.
1249269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestConnectivity("udp", port1, "udp", port2, true, true, true, true);
1250269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1251269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1252269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// This test is trying to validate a successful and failure scenario in a
1253269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// loopback test when protocol is RFC5245. For success IceTiebreaker, username
1254269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// should remain equal to the request generated by the port and role of port
1255269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// must be in controlling.
12567cbd188c5ed7df80bb737bd4ada94422730e2d89Peter ThatcherTEST_F(PortTest, TestLoopbackCal) {
1257269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<TestPort> lport(
1258269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
1259269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1260269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  lport->SetIceTiebreaker(kTiebreaker1);
1261269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  lport->PrepareAddress();
1262269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_FALSE(lport->Candidates().empty());
1263269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Connection* conn = lport->CreateConnection(lport->Candidates()[0],
1264269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                             Port::ORIGIN_MESSAGE);
1265269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  conn->Ping(0);
1266269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1267269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, 1000);
1268269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  IceMessage* msg = lport->last_stun_msg();
1269269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
1270269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  conn->OnReadPacket(lport->last_stun_buf()->Data(),
1271269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                     lport->last_stun_buf()->Length(),
1272269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                     rtc::PacketTime());
1273269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, 1000);
1274269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  msg = lport->last_stun_msg();
1275269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(STUN_BINDING_RESPONSE, msg->type());
1276269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1277269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // If the tiebreaker value is different from port, we expect a error
1278269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // response.
1279269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  lport->Reset();
1280269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  lport->AddCandidateAddress(kLocalAddr2);
128104ac81f2fd8ef6680522438fac1894db5415a0ecPeter Thatcher  // Creating a different connection as |conn| is receiving.
1282269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Connection* conn1 = lport->CreateConnection(lport->Candidates()[1],
1283269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                              Port::ORIGIN_MESSAGE);
1284269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  conn1->Ping(0);
1285269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1286269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, 1000);
1287269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  msg = lport->last_stun_msg();
1288269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
1289269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<IceMessage> modified_req(
1290269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      CreateStunMessage(STUN_BINDING_REQUEST));
1291269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  const StunByteStringAttribute* username_attr = msg->GetByteString(
1292269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      STUN_ATTR_USERNAME);
1293269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  modified_req->AddAttribute(new StunByteStringAttribute(
1294269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      STUN_ATTR_USERNAME, username_attr->GetString()));
1295269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // To make sure we receive error response, adding tiebreaker less than
1296269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // what's present in request.
1297269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  modified_req->AddAttribute(new StunUInt64Attribute(
1298269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      STUN_ATTR_ICE_CONTROLLING, kTiebreaker1 - 1));
1299269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  modified_req->AddMessageIntegrity("lpass");
1300269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  modified_req->AddFingerprint();
1301269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1302269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  lport->Reset();
1303269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
1304269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  WriteStunMessage(modified_req.get(), buf.get());
1305269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  conn1->OnReadPacket(buf->Data(), buf->Length(), rtc::PacketTime());
1306269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, 1000);
1307269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  msg = lport->last_stun_msg();
1308269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, msg->type());
1309269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1310269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1311269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// This test verifies role conflict signal is received when there is
1312269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// conflict in the role. In this case both ports are in controlling and
1313269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// |rport| has higher tiebreaker value than |lport|. Since |lport| has lower
1314269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// value of tiebreaker, when it receives ping request from |rport| it will
1315269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// send role conflict signal.
1316269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestIceRoleConflict) {
1317269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<TestPort> lport(
1318269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
1319269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1320269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  lport->SetIceTiebreaker(kTiebreaker1);
1321269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<TestPort> rport(
1322269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1323269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1324269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rport->SetIceTiebreaker(kTiebreaker2);
1325269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1326269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  lport->PrepareAddress();
1327269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rport->PrepareAddress();
1328269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_FALSE(lport->Candidates().empty());
1329269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_FALSE(rport->Candidates().empty());
1330269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Connection* lconn = lport->CreateConnection(rport->Candidates()[0],
1331269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                              Port::ORIGIN_MESSAGE);
1332269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Connection* rconn = rport->CreateConnection(lport->Candidates()[0],
1333269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                              Port::ORIGIN_MESSAGE);
1334269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rconn->Ping(0);
1335269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1336269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE_WAIT(rport->last_stun_msg() != NULL, 1000);
1337269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  IceMessage* msg = rport->last_stun_msg();
1338269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
1339269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Send rport binding request to lport.
1340269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  lconn->OnReadPacket(rport->last_stun_buf()->Data(),
1341269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                      rport->last_stun_buf()->Length(),
1342269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                      rtc::PacketTime());
1343269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1344269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, 1000);
1345269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(STUN_BINDING_RESPONSE, lport->last_stun_msg()->type());
1346269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(role_conflict());
1347269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1348269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1349269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestTcpNoDelay) {
1350269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TCPPort* port1 = CreateTcpPort(kLocalAddr1);
13517cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher  port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
1352269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  int option_value = -1;
1353269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  int success = port1->GetOption(rtc::Socket::OPT_NODELAY,
1354269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                 &option_value);
1355269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_EQ(0, success);  // GetOption() should complete successfully w/ 0
1356269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_EQ(1, option_value);
1357269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  delete port1;
1358269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1359269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1360269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestDelayedBindingUdp) {
1361269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  FakeAsyncPacketSocket *socket = new FakeAsyncPacketSocket();
1362269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  FakePacketSocketFactory socket_factory;
1363269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1364269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  socket_factory.set_next_udp_socket(socket);
1365269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  scoped_ptr<UDPPort> port(
1366269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      CreateUdpPort(kLocalAddr1, &socket_factory));
1367269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1368269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  socket->set_state(AsyncPacketSocket::STATE_BINDING);
1369269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  port->PrepareAddress();
1370269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1371269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(0U, port->Candidates().size());
1372269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  socket->SignalAddressReady(socket, kLocalAddr2);
1373269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1374269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(1U, port->Candidates().size());
1375269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1376269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1377269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestDelayedBindingTcp) {
1378269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  FakeAsyncPacketSocket *socket = new FakeAsyncPacketSocket();
1379269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  FakePacketSocketFactory socket_factory;
1380269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1381269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  socket_factory.set_next_server_tcp_socket(socket);
1382269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  scoped_ptr<TCPPort> port(
1383269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      CreateTcpPort(kLocalAddr1, &socket_factory));
1384269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1385269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  socket->set_state(AsyncPacketSocket::STATE_BINDING);
1386269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  port->PrepareAddress();
1387269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1388269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(0U, port->Candidates().size());
1389269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  socket->SignalAddressReady(socket, kLocalAddr2);
1390269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1391269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(1U, port->Candidates().size());
1392269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1393269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1394269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgvoid PortTest::TestCrossFamilyPorts(int type) {
1395269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  FakePacketSocketFactory factory;
1396269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  scoped_ptr<Port> ports[4];
1397269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  SocketAddress addresses[4] = {SocketAddress("192.168.1.3", 0),
1398269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                SocketAddress("192.168.1.4", 0),
1399269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                SocketAddress("2001:db8::1", 0),
1400269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                SocketAddress("2001:db8::2", 0)};
1401269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  for (int i = 0; i < 4; i++) {
1402269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    FakeAsyncPacketSocket *socket = new FakeAsyncPacketSocket();
1403269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    if (type == SOCK_DGRAM) {
1404269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      factory.set_next_udp_socket(socket);
1405269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      ports[i].reset(CreateUdpPort(addresses[i], &factory));
1406269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    } else if (type == SOCK_STREAM) {
1407269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      factory.set_next_server_tcp_socket(socket);
1408269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      ports[i].reset(CreateTcpPort(addresses[i], &factory));
1409269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    }
1410269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    socket->set_state(AsyncPacketSocket::STATE_BINDING);
1411269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    socket->SignalAddressReady(socket, addresses[i]);
1412269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    ports[i]->PrepareAddress();
1413269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
1414269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1415269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // IPv4 Port, connects to IPv6 candidate and then to IPv4 candidate.
1416269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  if (type == SOCK_STREAM) {
1417269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    FakeAsyncPacketSocket* clientsocket = new FakeAsyncPacketSocket();
1418269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    factory.set_next_client_tcp_socket(clientsocket);
1419269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
1420269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Connection* c = ports[0]->CreateConnection(GetCandidate(ports[2].get()),
1421269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                             Port::ORIGIN_MESSAGE);
1422269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(NULL == c);
1423269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(0U, ports[0]->connections().size());
1424269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  c = ports[0]->CreateConnection(GetCandidate(ports[1].get()),
1425269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                 Port::ORIGIN_MESSAGE);
1426269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_FALSE(NULL == c);
1427269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(1U, ports[0]->connections().size());
1428269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1429269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // IPv6 Port, connects to IPv4 candidate and to IPv6 candidate.
1430269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  if (type == SOCK_STREAM) {
1431269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    FakeAsyncPacketSocket* clientsocket = new FakeAsyncPacketSocket();
1432269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    factory.set_next_client_tcp_socket(clientsocket);
1433269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
1434269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  c = ports[2]->CreateConnection(GetCandidate(ports[0].get()),
1435269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                 Port::ORIGIN_MESSAGE);
1436269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(NULL == c);
1437269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(0U, ports[2]->connections().size());
1438269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  c = ports[2]->CreateConnection(GetCandidate(ports[3].get()),
1439269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                 Port::ORIGIN_MESSAGE);
1440269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_FALSE(NULL == c);
1441269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(1U, ports[2]->connections().size());
1442269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1443269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1444269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestSkipCrossFamilyTcp) {
1445269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestCrossFamilyPorts(SOCK_STREAM);
1446269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1447269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1448269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestSkipCrossFamilyUdp) {
1449269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestCrossFamilyPorts(SOCK_DGRAM);
1450269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1451269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1452b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatchervoid PortTest::ExpectPortsCanConnect(bool can_connect, Port* p1, Port* p2) {
1453b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher  Connection* c = p1->CreateConnection(GetCandidate(p2),
1454b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher                                       Port::ORIGIN_MESSAGE);
1455b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher  if (can_connect) {
1456b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher    EXPECT_FALSE(NULL == c);
1457b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher    EXPECT_EQ(1U, p1->connections().size());
1458b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher  } else {
1459b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher    EXPECT_TRUE(NULL == c);
1460b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher    EXPECT_EQ(0U, p1->connections().size());
1461b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher  }
1462b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher}
1463b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher
1464b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter ThatcherTEST_F(PortTest, TestUdpV6CrossTypePorts) {
1465b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher  FakePacketSocketFactory factory;
1466b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher  scoped_ptr<Port> ports[4];
1467b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher  SocketAddress addresses[4] = {SocketAddress("2001:db8::1", 0),
1468b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher                                SocketAddress("fe80::1", 0),
1469b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher                                SocketAddress("fe80::2", 0),
1470b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher                                SocketAddress("::1", 0)};
1471b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher  for (int i = 0; i < 4; i++) {
1472b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher    FakeAsyncPacketSocket *socket = new FakeAsyncPacketSocket();
1473b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher    factory.set_next_udp_socket(socket);
1474b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher    ports[i].reset(CreateUdpPort(addresses[i], &factory));
1475b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher    socket->set_state(AsyncPacketSocket::STATE_BINDING);
1476b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher    socket->SignalAddressReady(socket, addresses[i]);
1477b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher    ports[i]->PrepareAddress();
1478b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher  }
1479b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher
1480b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher  Port* standard = ports[0].get();
1481b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher  Port* link_local1 = ports[1].get();
1482b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher  Port* link_local2 = ports[2].get();
1483b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher  Port* localhost = ports[3].get();
1484b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher
1485b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher  ExpectPortsCanConnect(false, link_local1, standard);
1486b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher  ExpectPortsCanConnect(false, standard, link_local1);
1487b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher  ExpectPortsCanConnect(false, link_local1, localhost);
1488b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher  ExpectPortsCanConnect(false, localhost, link_local1);
1489b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher
1490b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher  ExpectPortsCanConnect(true, link_local1, link_local2);
1491b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher  ExpectPortsCanConnect(true, localhost, standard);
1492b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher  ExpectPortsCanConnect(true, standard, localhost);
1493b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher}
1494b8b0143a11afd495b8e9c1a1cc388cdbd4340b99Peter Thatcher
1495269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// This test verifies DSCP value set through SetOption interface can be
1496269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// get through DefaultDscpValue.
1497269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestDefaultDscpValue) {
1498269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  int dscp;
1499269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<UDPPort> udpport(CreateUdpPort(kLocalAddr1));
1500269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(0, udpport->SetOption(rtc::Socket::OPT_DSCP,
1501269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                  rtc::DSCP_CS6));
1502269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(0, udpport->GetOption(rtc::Socket::OPT_DSCP, &dscp));
1503269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<TCPPort> tcpport(CreateTcpPort(kLocalAddr1));
1504269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(0, tcpport->SetOption(rtc::Socket::OPT_DSCP,
1505269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                 rtc::DSCP_AF31));
1506269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(0, tcpport->GetOption(rtc::Socket::OPT_DSCP, &dscp));
1507269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(rtc::DSCP_AF31, dscp);
1508269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<StunPort> stunport(
1509269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      CreateStunPort(kLocalAddr1, nat_socket_factory1()));
1510269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(0, stunport->SetOption(rtc::Socket::OPT_DSCP,
1511269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                  rtc::DSCP_AF41));
1512269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(0, stunport->GetOption(rtc::Socket::OPT_DSCP, &dscp));
1513269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(rtc::DSCP_AF41, dscp);
1514269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<TurnPort> turnport1(CreateTurnPort(
1515269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
1516269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Socket is created in PrepareAddress.
1517269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  turnport1->PrepareAddress();
1518269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(0, turnport1->SetOption(rtc::Socket::OPT_DSCP,
1519269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                  rtc::DSCP_CS7));
1520269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(0, turnport1->GetOption(rtc::Socket::OPT_DSCP, &dscp));
1521269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(rtc::DSCP_CS7, dscp);
1522269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // This will verify correct value returned without the socket.
1523269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<TurnPort> turnport2(CreateTurnPort(
1524269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
1525269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(0, turnport2->SetOption(rtc::Socket::OPT_DSCP,
1526269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                  rtc::DSCP_CS6));
1527269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(0, turnport2->GetOption(rtc::Socket::OPT_DSCP, &dscp));
1528269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(rtc::DSCP_CS6, dscp);
1529269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1530269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
15317cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher// Test sending STUN messages.
15327cbd188c5ed7df80bb737bd4ada94422730e2d89Peter ThatcherTEST_F(PortTest, TestSendStunMessage) {
1533269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<TestPort> lport(
1534269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
1535269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<TestPort> rport(
1536269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1537269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1538269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  lport->SetIceTiebreaker(kTiebreaker1);
1539269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
1540269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rport->SetIceTiebreaker(kTiebreaker2);
1541269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1542269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Send a fake ping from lport to rport.
1543269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  lport->PrepareAddress();
1544269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rport->PrepareAddress();
1545269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_FALSE(rport->Candidates().empty());
1546269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Connection* lconn = lport->CreateConnection(
1547269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      rport->Candidates()[0], Port::ORIGIN_MESSAGE);
1548269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Connection* rconn = rport->CreateConnection(
1549269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      lport->Candidates()[0], Port::ORIGIN_MESSAGE);
1550269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  lconn->Ping(0);
1551269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1552269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Check that it's a proper BINDING-REQUEST.
1553269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, 1000);
1554269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  IceMessage* msg = lport->last_stun_msg();
1555269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
1556269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_FALSE(msg->IsLegacy());
1557269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  const StunByteStringAttribute* username_attr =
1558269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      msg->GetByteString(STUN_ATTR_USERNAME);
1559269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(username_attr != NULL);
1560269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  const StunUInt32Attribute* priority_attr = msg->GetUInt32(STUN_ATTR_PRIORITY);
1561269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(priority_attr != NULL);
1562269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(kDefaultPrflxPriority, priority_attr->value());
1563269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ("rfrag:lfrag", username_attr->GetString());
1564269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL);
1565269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(StunMessage::ValidateMessageIntegrity(
1566269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      lport->last_stun_buf()->Data(), lport->last_stun_buf()->Length(),
1567269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      "rpass"));
1568269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  const StunUInt64Attribute* ice_controlling_attr =
1569269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      msg->GetUInt64(STUN_ATTR_ICE_CONTROLLING);
1570269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(ice_controlling_attr != NULL);
1571269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(lport->IceTiebreaker(), ice_controlling_attr->value());
1572269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(msg->GetByteString(STUN_ATTR_ICE_CONTROLLED) == NULL);
1573269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) != NULL);
1574269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(msg->GetUInt32(STUN_ATTR_FINGERPRINT) != NULL);
1575269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(StunMessage::ValidateFingerprint(
1576269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      lport->last_stun_buf()->Data(), lport->last_stun_buf()->Length()));
1577269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1578269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Request should not include ping count.
1579269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(msg->GetUInt32(STUN_ATTR_RETRANSMIT_COUNT) == NULL);
1580269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1581269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Save a copy of the BINDING-REQUEST for use below.
1582269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<IceMessage> request(CopyStunMessage(msg));
1583269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1584269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Respond with a BINDING-RESPONSE.
1585269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rport->SendBindingResponse(request.get(), lport->Candidates()[0].address());
1586269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  msg = rport->last_stun_msg();
1587269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(msg != NULL);
1588269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(STUN_BINDING_RESPONSE, msg->type());
1589269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1590269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1591269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_FALSE(msg->IsLegacy());
1592269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  const StunAddressAttribute* addr_attr = msg->GetAddress(
1593269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      STUN_ATTR_XOR_MAPPED_ADDRESS);
1594269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(addr_attr != NULL);
1595269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(lport->Candidates()[0].address(), addr_attr->GetAddress());
1596269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL);
1597269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(StunMessage::ValidateMessageIntegrity(
1598269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      rport->last_stun_buf()->Data(), rport->last_stun_buf()->Length(),
1599269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      "rpass"));
1600269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(msg->GetUInt32(STUN_ATTR_FINGERPRINT) != NULL);
1601269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(StunMessage::ValidateFingerprint(
1602269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      lport->last_stun_buf()->Data(), lport->last_stun_buf()->Length()));
1603269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // No USERNAME or PRIORITY in ICE responses.
1604269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USERNAME) == NULL);
1605269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(msg->GetByteString(STUN_ATTR_PRIORITY) == NULL);
1606269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MAPPED_ADDRESS) == NULL);
1607269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(msg->GetByteString(STUN_ATTR_ICE_CONTROLLING) == NULL);
1608269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(msg->GetByteString(STUN_ATTR_ICE_CONTROLLED) == NULL);
1609269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) == NULL);
1610269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1611269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Response should not include ping count.
1612269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(msg->GetUInt32(STUN_ATTR_RETRANSMIT_COUNT) == NULL);
1613269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1614269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Respond with a BINDING-ERROR-RESPONSE. This wouldn't happen in real life,
1615269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // but we can do it here.
1616269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rport->SendBindingErrorResponse(request.get(),
1617269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                  lport->Candidates()[0].address(),
1618269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                  STUN_ERROR_SERVER_ERROR,
1619269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                  STUN_ERROR_REASON_SERVER_ERROR);
1620269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  msg = rport->last_stun_msg();
1621269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(msg != NULL);
1622269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(STUN_BINDING_ERROR_RESPONSE, msg->type());
1623269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_FALSE(msg->IsLegacy());
1624269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  const StunErrorCodeAttribute* error_attr = msg->GetErrorCode();
1625269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(error_attr != NULL);
1626269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(STUN_ERROR_SERVER_ERROR, error_attr->code());
1627269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(std::string(STUN_ERROR_REASON_SERVER_ERROR), error_attr->reason());
1628269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY) != NULL);
1629269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(StunMessage::ValidateMessageIntegrity(
1630269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      rport->last_stun_buf()->Data(), rport->last_stun_buf()->Length(),
1631269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      "rpass"));
1632269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(msg->GetUInt32(STUN_ATTR_FINGERPRINT) != NULL);
1633269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(StunMessage::ValidateFingerprint(
1634269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      lport->last_stun_buf()->Data(), lport->last_stun_buf()->Length()));
1635269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // No USERNAME with ICE.
1636269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USERNAME) == NULL);
1637269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(msg->GetByteString(STUN_ATTR_PRIORITY) == NULL);
1638269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1639269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Testing STUN binding requests from rport --> lport, having ICE_CONTROLLED
1640269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // and (incremented) RETRANSMIT_COUNT attributes.
1641269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rport->Reset();
1642269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rport->set_send_retransmit_count_attribute(true);
1643269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rconn->Ping(0);
1644269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rconn->Ping(0);
1645269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rconn->Ping(0);
1646269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE_WAIT(rport->last_stun_msg() != NULL, 1000);
1647269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  msg = rport->last_stun_msg();
1648269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
1649269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  const StunUInt64Attribute* ice_controlled_attr =
1650269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      msg->GetUInt64(STUN_ATTR_ICE_CONTROLLED);
1651269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(ice_controlled_attr != NULL);
1652269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(rport->IceTiebreaker(), ice_controlled_attr->value());
1653269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) == NULL);
1654269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1655269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Request should include ping count.
1656269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  const StunUInt32Attribute* retransmit_attr =
1657269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      msg->GetUInt32(STUN_ATTR_RETRANSMIT_COUNT);
1658269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(retransmit_attr != NULL);
1659269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(2U, retransmit_attr->value());
1660269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1661269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Respond with a BINDING-RESPONSE.
1662269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  request.reset(CopyStunMessage(msg));
1663269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  lport->SendBindingResponse(request.get(), rport->Candidates()[0].address());
1664269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  msg = lport->last_stun_msg();
1665269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1666269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Response should include same ping count.
1667269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  retransmit_attr = msg->GetUInt32(STUN_ATTR_RETRANSMIT_COUNT);
1668269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(retransmit_attr != NULL);
1669269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(2U, retransmit_attr->value());
1670269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1671269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1672269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestUseCandidateAttribute) {
1673269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<TestPort> lport(
1674269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
1675269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<TestPort> rport(
1676269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1677269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1678269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  lport->SetIceTiebreaker(kTiebreaker1);
1679269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
1680269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rport->SetIceTiebreaker(kTiebreaker2);
1681269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1682269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Send a fake ping from lport to rport.
1683269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  lport->PrepareAddress();
1684269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rport->PrepareAddress();
1685269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_FALSE(rport->Candidates().empty());
1686269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Connection* lconn = lport->CreateConnection(
1687269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      rport->Candidates()[0], Port::ORIGIN_MESSAGE);
1688269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  lconn->Ping(0);
1689269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, 1000);
1690269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  IceMessage* msg = lport->last_stun_msg();
1691269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  const StunUInt64Attribute* ice_controlling_attr =
1692269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      msg->GetUInt64(STUN_ATTR_ICE_CONTROLLING);
1693269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(ice_controlling_attr != NULL);
1694269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  const StunByteStringAttribute* use_candidate_attr = msg->GetByteString(
1695269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      STUN_ATTR_USE_CANDIDATE);
1696269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(use_candidate_attr != NULL);
1697269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1698269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
16997cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher// Test handling STUN messages.
17007cbd188c5ed7df80bb737bd4ada94422730e2d89Peter ThatcherTEST_F(PortTest, TestHandleStunMessage) {
1701269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Our port will act as the "remote" port.
1702269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<TestPort> port(
1703269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1704269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1705269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<IceMessage> in_msg, out_msg;
1706269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
1707269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::SocketAddress addr(kLocalAddr1);
1708269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  std::string username;
1709269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1710269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // BINDING-REQUEST from local to remote with valid ICE username,
1711269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // MESSAGE-INTEGRITY, and FINGERPRINT.
1712269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
1713269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                             "rfrag:lfrag"));
1714269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg->AddMessageIntegrity("rpass");
1715269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg->AddFingerprint();
1716269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  WriteStunMessage(in_msg.get(), buf.get());
1717269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1718269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                   out_msg.accept(), &username));
1719269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(out_msg.get() != NULL);
1720269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ("lfrag", username);
1721269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1722269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // BINDING-RESPONSE without username, with MESSAGE-INTEGRITY and FINGERPRINT.
1723269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg.reset(CreateStunMessage(STUN_BINDING_RESPONSE));
1724269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg->AddAttribute(
1725269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      new StunXorAddressAttribute(STUN_ATTR_XOR_MAPPED_ADDRESS, kLocalAddr2));
1726269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg->AddMessageIntegrity("rpass");
1727269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg->AddFingerprint();
1728269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  WriteStunMessage(in_msg.get(), buf.get());
1729269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1730269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                   out_msg.accept(), &username));
1731269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(out_msg.get() != NULL);
1732269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ("", username);
1733269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1734269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // BINDING-ERROR-RESPONSE without username, with error, M-I, and FINGERPRINT.
1735269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg.reset(CreateStunMessage(STUN_BINDING_ERROR_RESPONSE));
1736269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg->AddAttribute(new StunErrorCodeAttribute(STUN_ATTR_ERROR_CODE,
1737269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      STUN_ERROR_SERVER_ERROR, STUN_ERROR_REASON_SERVER_ERROR));
1738269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg->AddFingerprint();
1739269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  WriteStunMessage(in_msg.get(), buf.get());
1740269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1741269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                   out_msg.accept(), &username));
1742269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(out_msg.get() != NULL);
1743269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ("", username);
1744269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(out_msg->GetErrorCode() != NULL);
1745269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(STUN_ERROR_SERVER_ERROR, out_msg->GetErrorCode()->code());
1746269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(std::string(STUN_ERROR_REASON_SERVER_ERROR),
1747269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      out_msg->GetErrorCode()->reason());
1748269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1749269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1750269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// Tests handling of ICE binding requests with missing or incorrect usernames.
17517cbd188c5ed7df80bb737bd4ada94422730e2d89Peter ThatcherTEST_F(PortTest, TestHandleStunMessageBadUsername) {
1752269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<TestPort> port(
1753269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1754269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1755269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<IceMessage> in_msg, out_msg;
1756269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
1757269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::SocketAddress addr(kLocalAddr1);
1758269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  std::string username;
1759269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1760269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // BINDING-REQUEST with no username.
1761269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg.reset(CreateStunMessage(STUN_BINDING_REQUEST));
1762269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg->AddMessageIntegrity("rpass");
1763269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg->AddFingerprint();
1764269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  WriteStunMessage(in_msg.get(), buf.get());
1765269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1766269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                   out_msg.accept(), &username));
1767269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(out_msg.get() == NULL);
1768269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ("", username);
1769269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(STUN_ERROR_BAD_REQUEST, port->last_stun_error_code());
1770269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1771269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // BINDING-REQUEST with empty username.
1772269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST, ""));
1773269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg->AddMessageIntegrity("rpass");
1774269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg->AddFingerprint();
1775269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  WriteStunMessage(in_msg.get(), buf.get());
1776269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1777269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                   out_msg.accept(), &username));
1778269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(out_msg.get() == NULL);
1779269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ("", username);
1780269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
1781269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1782269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // BINDING-REQUEST with too-short username.
1783269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST, "rfra"));
1784269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg->AddMessageIntegrity("rpass");
1785269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg->AddFingerprint();
1786269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  WriteStunMessage(in_msg.get(), buf.get());
1787269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1788269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                   out_msg.accept(), &username));
1789269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(out_msg.get() == NULL);
1790269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ("", username);
1791269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
1792269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1793269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // BINDING-REQUEST with reversed username.
1794269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
1795269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                            "lfrag:rfrag"));
1796269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg->AddMessageIntegrity("rpass");
1797269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg->AddFingerprint();
1798269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  WriteStunMessage(in_msg.get(), buf.get());
1799269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1800269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                   out_msg.accept(), &username));
1801269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(out_msg.get() == NULL);
1802269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ("", username);
1803269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
1804269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1805269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // BINDING-REQUEST with garbage username.
1806269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
1807269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                             "abcd:efgh"));
1808269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg->AddMessageIntegrity("rpass");
1809269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg->AddFingerprint();
1810269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  WriteStunMessage(in_msg.get(), buf.get());
1811269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1812269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                   out_msg.accept(), &username));
1813269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(out_msg.get() == NULL);
1814269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ("", username);
1815269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
1816269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1817269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
18187cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher// Test handling STUN messages with missing or malformed M-I.
18197cbd188c5ed7df80bb737bd4ada94422730e2d89Peter ThatcherTEST_F(PortTest, TestHandleStunMessageBadMessageIntegrity) {
1820269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Our port will act as the "remote" port.
1821269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<TestPort> port(
1822269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1823269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1824269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<IceMessage> in_msg, out_msg;
1825269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
1826269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::SocketAddress addr(kLocalAddr1);
1827269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  std::string username;
1828269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1829269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // BINDING-REQUEST from local to remote with valid ICE username and
1830269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // FINGERPRINT, but no MESSAGE-INTEGRITY.
1831269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
1832269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                             "rfrag:lfrag"));
1833269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg->AddFingerprint();
1834269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  WriteStunMessage(in_msg.get(), buf.get());
1835269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1836269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                   out_msg.accept(), &username));
1837269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(out_msg.get() == NULL);
1838269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ("", username);
1839269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(STUN_ERROR_BAD_REQUEST, port->last_stun_error_code());
1840269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1841269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // BINDING-REQUEST from local to remote with valid ICE username and
1842269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // FINGERPRINT, but invalid MESSAGE-INTEGRITY.
1843269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
1844269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                             "rfrag:lfrag"));
1845269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg->AddMessageIntegrity("invalid");
1846269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg->AddFingerprint();
1847269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  WriteStunMessage(in_msg.get(), buf.get());
1848269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1849269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                   out_msg.accept(), &username));
1850269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(out_msg.get() == NULL);
1851269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ("", username);
1852269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(STUN_ERROR_UNAUTHORIZED, port->last_stun_error_code());
1853269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1854269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // TODO: BINDING-RESPONSES and BINDING-ERROR-RESPONSES are checked
1855269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // by the Connection, not the Port, since they require the remote username.
1856269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Change this test to pass in data via Connection::OnReadPacket instead.
1857269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1858269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
18597cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher// Test handling STUN messages with missing or malformed FINGERPRINT.
18607cbd188c5ed7df80bb737bd4ada94422730e2d89Peter ThatcherTEST_F(PortTest, TestHandleStunMessageBadFingerprint) {
1861269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Our port will act as the "remote" port.
1862269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<TestPort> port(
1863269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1864269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1865269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<IceMessage> in_msg, out_msg;
1866269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
1867269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::SocketAddress addr(kLocalAddr1);
1868269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  std::string username;
1869269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1870269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // BINDING-REQUEST from local to remote with valid ICE username and
1871269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // MESSAGE-INTEGRITY, but no FINGERPRINT; GetStunMessage should fail.
1872269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg.reset(CreateStunMessageWithUsername(STUN_BINDING_REQUEST,
1873269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                             "rfrag:lfrag"));
1874269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg->AddMessageIntegrity("rpass");
1875269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  WriteStunMessage(in_msg.get(), buf.get());
1876269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1877269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                    out_msg.accept(), &username));
1878269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(0, port->last_stun_error_code());
1879269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1880269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Now, add a fingerprint, but munge the message so it's not valid.
1881269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg->AddFingerprint();
1882269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg->SetTransactionID("TESTTESTBADD");
1883269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  WriteStunMessage(in_msg.get(), buf.get());
1884269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1885269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                    out_msg.accept(), &username));
1886269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(0, port->last_stun_error_code());
1887269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1888269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Valid BINDING-RESPONSE, except no FINGERPRINT.
1889269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg.reset(CreateStunMessage(STUN_BINDING_RESPONSE));
1890269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg->AddAttribute(
1891269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      new StunXorAddressAttribute(STUN_ATTR_XOR_MAPPED_ADDRESS, kLocalAddr2));
1892269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg->AddMessageIntegrity("rpass");
1893269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  WriteStunMessage(in_msg.get(), buf.get());
1894269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1895269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                    out_msg.accept(), &username));
1896269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(0, port->last_stun_error_code());
1897269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1898269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Now, add a fingerprint, but munge the message so it's not valid.
1899269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg->AddFingerprint();
1900269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg->SetTransactionID("TESTTESTBADD");
1901269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  WriteStunMessage(in_msg.get(), buf.get());
1902269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1903269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                    out_msg.accept(), &username));
1904269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(0, port->last_stun_error_code());
1905269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1906269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Valid BINDING-ERROR-RESPONSE, except no FINGERPRINT.
1907269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg.reset(CreateStunMessage(STUN_BINDING_ERROR_RESPONSE));
1908269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg->AddAttribute(new StunErrorCodeAttribute(STUN_ATTR_ERROR_CODE,
1909269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      STUN_ERROR_SERVER_ERROR, STUN_ERROR_REASON_SERVER_ERROR));
1910269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg->AddMessageIntegrity("rpass");
1911269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  WriteStunMessage(in_msg.get(), buf.get());
1912269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1913269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                    out_msg.accept(), &username));
1914269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(0, port->last_stun_error_code());
1915269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1916269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Now, add a fingerprint, but munge the message so it's not valid.
1917269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg->AddFingerprint();
1918269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg->SetTransactionID("TESTTESTBADD");
1919269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  WriteStunMessage(in_msg.get(), buf.get());
1920269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_FALSE(port->GetStunMessage(buf->Data(), buf->Length(), addr,
1921269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                    out_msg.accept(), &username));
1922269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(0, port->last_stun_error_code());
1923269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1924269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
19257cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher// Test handling of STUN binding indication messages . STUN binding
1926269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// indications are allowed only to the connection which is in read mode.
1927269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestHandleStunBindingIndication) {
1928269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<TestPort> lport(
1929269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      CreateTestPort(kLocalAddr2, "lfrag", "lpass"));
1930269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
1931269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  lport->SetIceTiebreaker(kTiebreaker1);
1932269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1933269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Verifying encoding and decoding STUN indication message.
1934269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<IceMessage> in_msg, out_msg;
1935269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<ByteBuffer> buf(new ByteBuffer());
1936269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::SocketAddress addr(kLocalAddr1);
1937269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  std::string username;
1938269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1939269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg.reset(CreateStunMessage(STUN_BINDING_INDICATION));
1940269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  in_msg->AddFingerprint();
1941269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  WriteStunMessage(in_msg.get(), buf.get());
1942269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(lport->GetStunMessage(buf->Data(), buf->Length(), addr,
1943269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                    out_msg.accept(), &username));
1944269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(out_msg.get() != NULL);
1945269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(out_msg->type(), STUN_BINDING_INDICATION);
1946269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ("", username);
1947269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1948269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Verify connection can handle STUN indication and updates
1949269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // last_ping_received.
1950269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<TestPort> rport(
1951269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
1952269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
1953269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rport->SetIceTiebreaker(kTiebreaker2);
1954269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1955269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  lport->PrepareAddress();
1956269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rport->PrepareAddress();
1957269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_FALSE(lport->Candidates().empty());
1958269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_FALSE(rport->Candidates().empty());
1959269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1960269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Connection* lconn = lport->CreateConnection(rport->Candidates()[0],
1961269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                              Port::ORIGIN_MESSAGE);
1962269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Connection* rconn = rport->CreateConnection(lport->Candidates()[0],
1963269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                              Port::ORIGIN_MESSAGE);
1964269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rconn->Ping(0);
1965269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1966269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE_WAIT(rport->last_stun_msg() != NULL, 1000);
1967269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  IceMessage* msg = rport->last_stun_msg();
1968269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(STUN_BINDING_REQUEST, msg->type());
1969269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Send rport binding request to lport.
1970269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  lconn->OnReadPacket(rport->last_stun_buf()->Data(),
1971269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                      rport->last_stun_buf()->Length(),
1972269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                      rtc::PacketTime());
1973269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE_WAIT(lport->last_stun_msg() != NULL, 1000);
1974269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(STUN_BINDING_RESPONSE, lport->last_stun_msg()->type());
19750c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  uint32_t last_ping_received1 = lconn->last_ping_received();
1976269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1977269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Adding a delay of 100ms.
1978269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::Thread::Current()->ProcessMessages(100);
1979269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Pinging lconn using stun indication message.
1980269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  lconn->OnReadPacket(buf->Data(), buf->Length(), rtc::PacketTime());
19810c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  uint32_t last_ping_received2 = lconn->last_ping_received();
1982269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_GT(last_ping_received2, last_ping_received1);
1983269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
1984269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
1985269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestComputeCandidatePriority) {
1986269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<TestPort> port(
1987269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      CreateTestPort(kLocalAddr1, "name", "pass"));
1988269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  port->set_type_preference(90);
1989269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  port->set_component(177);
1990269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  port->AddCandidateAddress(SocketAddress("192.168.1.4", 1234));
1991269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  port->AddCandidateAddress(SocketAddress("2001:db8::1234", 1234));
1992269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  port->AddCandidateAddress(SocketAddress("fc12:3456::1234", 1234));
1993269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  port->AddCandidateAddress(SocketAddress("::ffff:192.168.1.4", 1234));
1994269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  port->AddCandidateAddress(SocketAddress("::192.168.1.4", 1234));
1995269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  port->AddCandidateAddress(SocketAddress("2002::1234:5678", 1234));
1996269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  port->AddCandidateAddress(SocketAddress("2001::1234:5678", 1234));
1997269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  port->AddCandidateAddress(SocketAddress("fecf::1234:5678", 1234));
1998269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  port->AddCandidateAddress(SocketAddress("3ffe::1234:5678", 1234));
1999269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // These should all be:
2000269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // (90 << 24) | ([rfc3484 pref value] << 8) | (256 - 177)
20010c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  uint32_t expected_priority_v4 = 1509957199U;
20020c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  uint32_t expected_priority_v6 = 1509959759U;
20030c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  uint32_t expected_priority_ula = 1509962319U;
20040c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  uint32_t expected_priority_v4mapped = expected_priority_v4;
20050c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  uint32_t expected_priority_v4compat = 1509949775U;
20060c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  uint32_t expected_priority_6to4 = 1509954639U;
20070c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  uint32_t expected_priority_teredo = 1509952079U;
20080c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  uint32_t expected_priority_sitelocal = 1509949775U;
20090c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  uint32_t expected_priority_6bone = 1509949775U;
2010269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_EQ(expected_priority_v4, port->Candidates()[0].priority());
2011269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_EQ(expected_priority_v6, port->Candidates()[1].priority());
2012269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_EQ(expected_priority_ula, port->Candidates()[2].priority());
2013269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_EQ(expected_priority_v4mapped, port->Candidates()[3].priority());
2014269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_EQ(expected_priority_v4compat, port->Candidates()[4].priority());
2015269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_EQ(expected_priority_6to4, port->Candidates()[5].priority());
2016269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_EQ(expected_priority_teredo, port->Candidates()[6].priority());
2017269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_EQ(expected_priority_sitelocal, port->Candidates()[7].priority());
2018269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_EQ(expected_priority_6bone, port->Candidates()[8].priority());
2019269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
2020269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2021269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// In the case of shared socket, one port may be shared by local and stun.
2022269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// Test that candidates with different types will have different foundation.
2023269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestFoundation) {
2024269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<TestPort> testport(
2025269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      CreateTestPort(kLocalAddr1, "name", "pass"));
2026269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  testport->AddCandidateAddress(kLocalAddr1, kLocalAddr1,
2027269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                LOCAL_PORT_TYPE,
2028269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                cricket::ICE_TYPE_PREFERENCE_HOST, false);
2029269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  testport->AddCandidateAddress(kLocalAddr2, kLocalAddr1,
2030269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                STUN_PORT_TYPE,
2031269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                                cricket::ICE_TYPE_PREFERENCE_SRFLX, true);
2032269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_NE(testport->Candidates()[0].foundation(),
2033269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org            testport->Candidates()[1].foundation());
2034269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
2035269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2036269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// This test verifies the foundation of different types of ICE candidates.
2037269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestCandidateFoundation) {
2038269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<rtc::NATServer> nat_server(
2039269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      CreateNatServer(kNatAddr1, NAT_OPEN_CONE));
2040269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<UDPPort> udpport1(CreateUdpPort(kLocalAddr1));
2041269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  udpport1->PrepareAddress();
2042269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<UDPPort> udpport2(CreateUdpPort(kLocalAddr1));
2043269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  udpport2->PrepareAddress();
2044269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(udpport1->Candidates()[0].foundation(),
2045269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org            udpport2->Candidates()[0].foundation());
2046269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<TCPPort> tcpport1(CreateTcpPort(kLocalAddr1));
2047269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  tcpport1->PrepareAddress();
2048269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<TCPPort> tcpport2(CreateTcpPort(kLocalAddr1));
2049269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  tcpport2->PrepareAddress();
2050269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(tcpport1->Candidates()[0].foundation(),
2051269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org            tcpport2->Candidates()[0].foundation());
2052269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<Port> stunport(
2053269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      CreateStunPort(kLocalAddr1, nat_socket_factory1()));
2054269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  stunport->PrepareAddress();
2055269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_EQ_WAIT(1U, stunport->Candidates().size(), kTimeout);
2056269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_NE(tcpport1->Candidates()[0].foundation(),
2057269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org            stunport->Candidates()[0].foundation());
2058269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_NE(tcpport2->Candidates()[0].foundation(),
2059269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org            stunport->Candidates()[0].foundation());
2060269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_NE(udpport1->Candidates()[0].foundation(),
2061269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org            stunport->Candidates()[0].foundation());
2062269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_NE(udpport2->Candidates()[0].foundation(),
2063269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org            stunport->Candidates()[0].foundation());
2064269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Verify GTURN candidate foundation.
2065269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<RelayPort> relayport(
2066269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      CreateGturnPort(kLocalAddr1));
2067269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  relayport->AddServerAddress(
2068269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      cricket::ProtocolAddress(kRelayUdpIntAddr, cricket::PROTO_UDP));
2069269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  relayport->PrepareAddress();
2070269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_EQ_WAIT(1U, relayport->Candidates().size(), kTimeout);
2071269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_NE(udpport1->Candidates()[0].foundation(),
2072269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org            relayport->Candidates()[0].foundation());
2073269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_NE(udpport2->Candidates()[0].foundation(),
2074269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org            relayport->Candidates()[0].foundation());
2075269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Verifying TURN candidate foundation.
2076269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<Port> turnport1(CreateTurnPort(
2077269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
2078269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  turnport1->PrepareAddress();
2079269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_EQ_WAIT(1U, turnport1->Candidates().size(), kTimeout);
2080269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_NE(udpport1->Candidates()[0].foundation(),
2081269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org            turnport1->Candidates()[0].foundation());
2082269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_NE(udpport2->Candidates()[0].foundation(),
2083269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org            turnport1->Candidates()[0].foundation());
2084269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_NE(stunport->Candidates()[0].foundation(),
2085269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org            turnport1->Candidates()[0].foundation());
2086269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<Port> turnport2(CreateTurnPort(
2087269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
2088269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  turnport2->PrepareAddress();
2089269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_EQ_WAIT(1U, turnport2->Candidates().size(), kTimeout);
2090269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(turnport1->Candidates()[0].foundation(),
2091269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org            turnport2->Candidates()[0].foundation());
2092269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2093269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Running a second turn server, to get different base IP address.
2094269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  SocketAddress kTurnUdpIntAddr2("99.99.98.4", STUN_SERVER_PORT);
2095269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  SocketAddress kTurnUdpExtAddr2("99.99.98.5", 0);
2096269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestTurnServer turn_server2(
2097269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      rtc::Thread::Current(), kTurnUdpIntAddr2, kTurnUdpExtAddr2);
2098269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<Port> turnport3(CreateTurnPort(
2099269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP,
2100269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      kTurnUdpIntAddr2));
2101269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  turnport3->PrepareAddress();
2102269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_EQ_WAIT(1U, turnport3->Candidates().size(), kTimeout);
2103269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_NE(turnport3->Candidates()[0].foundation(),
2104269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org            turnport2->Candidates()[0].foundation());
2105269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
2106269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2107269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// This test verifies the related addresses of different types of
2108269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// ICE candiates.
2109269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestCandidateRelatedAddress) {
2110269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<rtc::NATServer> nat_server(
2111269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      CreateNatServer(kNatAddr1, NAT_OPEN_CONE));
2112269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<UDPPort> udpport(CreateUdpPort(kLocalAddr1));
2113269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  udpport->PrepareAddress();
2114269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // For UDPPort, related address will be empty.
2115269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(udpport->Candidates()[0].related_address().IsNil());
2116269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Testing related address for stun candidates.
2117269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // For stun candidate related address must be equal to the base
2118269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // socket address.
2119269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<StunPort> stunport(
2120269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      CreateStunPort(kLocalAddr1, nat_socket_factory1()));
2121269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  stunport->PrepareAddress();
2122269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_EQ_WAIT(1U, stunport->Candidates().size(), kTimeout);
2123269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Check STUN candidate address.
2124269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(stunport->Candidates()[0].address().ipaddr(),
2125269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org            kNatAddr1.ipaddr());
2126269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Check STUN candidate related address.
2127269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(stunport->Candidates()[0].related_address(),
2128269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org            stunport->GetLocalAddress());
2129269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Verifying the related address for the GTURN candidates.
2130269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // NOTE: In case of GTURN related address will be equal to the mapped
2131269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // address, but address(mapped) will not be XOR.
2132269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<RelayPort> relayport(
2133269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      CreateGturnPort(kLocalAddr1));
2134269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  relayport->AddServerAddress(
2135269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      cricket::ProtocolAddress(kRelayUdpIntAddr, cricket::PROTO_UDP));
2136269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  relayport->PrepareAddress();
2137269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_EQ_WAIT(1U, relayport->Candidates().size(), kTimeout);
2138269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // For Gturn related address is set to "0.0.0.0:0"
2139269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(rtc::SocketAddress(),
2140269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org            relayport->Candidates()[0].related_address());
2141269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Verifying the related address for TURN candidate.
2142269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // For TURN related address must be equal to the mapped address.
2143269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<Port> turnport(CreateTurnPort(
2144269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      kLocalAddr1, nat_socket_factory1(), PROTO_UDP, PROTO_UDP));
2145269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  turnport->PrepareAddress();
2146269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_EQ_WAIT(1U, turnport->Candidates().size(), kTimeout);
2147269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
2148269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org            turnport->Candidates()[0].address().ipaddr());
2149269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(kNatAddr1.ipaddr(),
2150269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org            turnport->Candidates()[0].related_address().ipaddr());
2151269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
2152269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2153269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// Test priority value overflow handling when preference is set to 3.
21547cbd188c5ed7df80bb737bd4ada94422730e2d89Peter ThatcherTEST_F(PortTest, TestCandidatePriority) {
2155269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  cricket::Candidate cand1;
21567cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher  cand1.set_priority(3);
2157269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  cricket::Candidate cand2;
21587cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher  cand2.set_priority(1);
21597cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher  EXPECT_TRUE(cand1.priority() > cand2.priority());
2160269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
2161269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2162269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// Test the Connection priority is calculated correctly.
2163269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestConnectionPriority) {
2164269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<TestPort> lport(
2165269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      CreateTestPort(kLocalAddr1, "lfrag", "lpass"));
2166269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  lport->set_type_preference(cricket::ICE_TYPE_PREFERENCE_HOST);
2167269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<TestPort> rport(
2168269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      CreateTestPort(kLocalAddr2, "rfrag", "rpass"));
2169269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rport->set_type_preference(cricket::ICE_TYPE_PREFERENCE_RELAY);
2170269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  lport->set_component(123);
2171269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  lport->AddCandidateAddress(SocketAddress("192.168.1.4", 1234));
2172269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rport->set_component(23);
2173269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rport->AddCandidateAddress(SocketAddress("10.1.1.100", 1234));
2174269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2175269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(0x7E001E85U, lport->Candidates()[0].priority());
2176269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(0x2001EE9U, rport->Candidates()[0].priority());
2177269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2178269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // RFC 5245
2179269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // pair priority = 2^32*MIN(G,D) + 2*MAX(G,D) + (G>D?1:0)
2180269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  lport->SetIceRole(cricket::ICEROLE_CONTROLLING);
2181269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rport->SetIceRole(cricket::ICEROLE_CONTROLLED);
2182269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Connection* lconn = lport->CreateConnection(
2183269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      rport->Candidates()[0], Port::ORIGIN_MESSAGE);
2184269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#if defined(WEBRTC_WIN)
2185269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(0x2001EE9FC003D0BU, lconn->priority());
2186269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#else
2187269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(0x2001EE9FC003D0BLLU, lconn->priority());
2188269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#endif
2189269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2190269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  lport->SetIceRole(cricket::ICEROLE_CONTROLLED);
2191269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rport->SetIceRole(cricket::ICEROLE_CONTROLLING);
2192269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  Connection* rconn = rport->CreateConnection(
2193269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      lport->Candidates()[0], Port::ORIGIN_MESSAGE);
2194269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#if defined(WEBRTC_WIN)
2195269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(0x2001EE9FC003D0AU, rconn->priority());
2196269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#else
2197269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(0x2001EE9FC003D0ALLU, rconn->priority());
2198269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org#endif
2199269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
2200269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2201269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestWritableState) {
2202269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  UDPPort* port1 = CreateUdpPort(kLocalAddr1);
22037cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher  port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
2204269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  UDPPort* port2 = CreateUdpPort(kLocalAddr2);
22057cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher  port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
2206269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2207269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Set up channels.
22081eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  TestChannel ch1(port1);
22091eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  TestChannel ch2(port2);
2210269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2211269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Acquire addresses.
2212269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ch1.Start();
2213269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ch2.Start();
2214269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_EQ_WAIT(1, ch1.complete_count(), kTimeout);
2215269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_EQ_WAIT(1, ch2.complete_count(), kTimeout);
2216269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2217269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Send a ping from src to dst.
22181eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  ch1.CreateConnection(GetCandidate(port2));
2219269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(ch1.conn() != NULL);
2220269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(Connection::STATE_WRITE_INIT, ch1.conn()->write_state());
2221269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE_WAIT(ch1.conn()->connected(), kTimeout);  // for TCP connect
2222269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ch1.Ping();
2223269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  WAIT(!ch2.remote_address().IsNil(), kTimeout);
2224269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2225269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Data should be unsendable until the connection is accepted.
2226269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  char data[] = "abcd";
2227269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  int data_size = ARRAY_SIZE(data);
2228269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::PacketOptions options;
2229269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(SOCKET_ERROR, ch1.conn()->Send(data, data_size, options));
2230269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2231269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Accept the connection to return the binding response, transition to
2232269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // writable, and allow data to be sent.
22331eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  ch2.AcceptConnection(GetCandidate(port1));
2234269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch1.conn()->write_state(),
2235269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                 kTimeout);
2236269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(data_size, ch1.conn()->Send(data, data_size, options));
2237269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2238269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Ask the connection to update state as if enough time has passed to lose
2239269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // full writability and 5 pings went unresponded to. We'll accomplish the
2240269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // latter by sending pings but not pumping messages.
22410c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  for (uint32_t i = 1; i <= CONNECTION_WRITE_CONNECT_FAILURES; ++i) {
2242269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    ch1.Ping(i);
2243269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
22440c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  uint32_t unreliable_timeout_delay = CONNECTION_WRITE_CONNECT_TIMEOUT + 500u;
2245269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ch1.conn()->UpdateState(unreliable_timeout_delay);
2246269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(Connection::STATE_WRITE_UNRELIABLE, ch1.conn()->write_state());
2247269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2248269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Data should be able to be sent in this state.
2249269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(data_size, ch1.conn()->Send(data, data_size, options));
2250269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2251269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // And now allow the other side to process the pings and send binding
2252269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // responses.
2253269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch1.conn()->write_state(),
2254269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                 kTimeout);
2255269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2256269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Wait long enough for a full timeout (past however long we've already
2257269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // waited).
22580c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  for (uint32_t i = 1; i <= CONNECTION_WRITE_CONNECT_FAILURES; ++i) {
2259269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    ch1.Ping(unreliable_timeout_delay + i);
2260269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
2261269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ch1.conn()->UpdateState(unreliable_timeout_delay + CONNECTION_WRITE_TIMEOUT +
2262269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                          500u);
2263269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(Connection::STATE_WRITE_TIMEOUT, ch1.conn()->write_state());
2264269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2265269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Now that the connection has completely timed out, data send should fail.
2266269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(SOCKET_ERROR, ch1.conn()->Send(data, data_size, options));
2267269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2268269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ch1.Stop();
2269269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ch2.Stop();
2270269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
2271269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2272269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestTimeoutForNeverWritable) {
2273269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  UDPPort* port1 = CreateUdpPort(kLocalAddr1);
22747cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher  port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
2275269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  UDPPort* port2 = CreateUdpPort(kLocalAddr2);
22767cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher  port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
2277269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2278269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Set up channels.
22791eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  TestChannel ch1(port1);
22801eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  TestChannel ch2(port2);
2281269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2282269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Acquire addresses.
2283269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ch1.Start();
2284269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ch2.Start();
2285269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
22861eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  ch1.CreateConnection(GetCandidate(port2));
2287269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(ch1.conn() != NULL);
2288269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(Connection::STATE_WRITE_INIT, ch1.conn()->write_state());
2289269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2290269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Attempt to go directly to write timeout.
22910c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  for (uint32_t i = 1; i <= CONNECTION_WRITE_CONNECT_FAILURES; ++i) {
2292269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org    ch1.Ping(i);
2293269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  }
2294269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ch1.conn()->UpdateState(CONNECTION_WRITE_TIMEOUT + 500u);
2295269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(Connection::STATE_WRITE_TIMEOUT, ch1.conn()->write_state());
2296269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
2297269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2298269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// This test verifies the connection setup between ICEMODE_FULL
2299269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// and ICEMODE_LITE.
2300269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// In this test |ch1| behaves like FULL mode client and we have created
2301269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// port which responds to the ping message just like LITE client.
2302269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestIceLiteConnectivity) {
2303269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  TestPort* ice_full_port = CreateTestPort(
23047cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher      kLocalAddr1, "lfrag", "lpass",
2305269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      cricket::ICEROLE_CONTROLLING, kTiebreaker1);
2306269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2307269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<TestPort> ice_lite_port(CreateTestPort(
23087cbd188c5ed7df80bb737bd4ada94422730e2d89Peter Thatcher      kLocalAddr2, "rfrag", "rpass",
2309269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      cricket::ICEROLE_CONTROLLED, kTiebreaker2));
2310269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Setup TestChannel. This behaves like FULL mode client.
23111eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  TestChannel ch1(ice_full_port);
2312269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ch1.SetIceMode(ICEMODE_FULL);
2313269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2314269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Start gathering candidates.
2315269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ch1.Start();
2316269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ice_lite_port->PrepareAddress();
2317269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2318269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_EQ_WAIT(1, ch1.complete_count(), kTimeout);
2319269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_FALSE(ice_lite_port->Candidates().empty());
2320269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
23211eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  ch1.CreateConnection(GetCandidate(ice_lite_port.get()));
2322269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE(ch1.conn() != NULL);
2323269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ(Connection::STATE_WRITE_INIT, ch1.conn()->write_state());
2324269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2325269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Send ping from full mode client.
2326269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // This ping must not have USE_CANDIDATE_ATTR.
2327269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ch1.Ping();
2328269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2329269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Verify stun ping is without USE_CANDIDATE_ATTR. Getting message directly
2330269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // from port.
2331269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE_WAIT(ice_full_port->last_stun_msg() != NULL, 1000);
2332269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  IceMessage* msg = ice_full_port->last_stun_msg();
2333269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) == NULL);
2334269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2335269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Respond with a BINDING-RESPONSE from litemode client.
2336269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // NOTE: Ideally we should't create connection at this stage from lite
2337269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // port, as it should be done only after receiving ping with USE_CANDIDATE.
2338269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // But we need a connection to send a response message.
2339269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ice_lite_port->CreateConnection(
2340269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      ice_full_port->Candidates()[0], cricket::Port::ORIGIN_MESSAGE);
2341269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::scoped_ptr<IceMessage> request(CopyStunMessage(msg));
2342269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ice_lite_port->SendBindingResponse(
2343269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org      request.get(), ice_full_port->Candidates()[0].address());
2344269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2345269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Feeding the respone message from litemode to the full mode connection.
2346269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ch1.conn()->OnReadPacket(ice_lite_port->last_stun_buf()->Data(),
2347269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                           ice_lite_port->last_stun_buf()->Length(),
2348269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                           rtc::PacketTime());
2349269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Verifying full mode connection becomes writable from the response.
2350269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, ch1.conn()->write_state(),
2351269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org                 kTimeout);
2352269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE_WAIT(ch1.nominated(), kTimeout);
2353269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2354269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Clear existing stun messsages. Otherwise we will process old stun
2355269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // message right after we send ping.
2356269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ice_full_port->Reset();
2357269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Send ping. This must have USE_CANDIDATE_ATTR.
2358269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ch1.Ping();
2359269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ASSERT_TRUE_WAIT(ice_full_port->last_stun_msg() != NULL, 1000);
2360269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  msg = ice_full_port->last_stun_msg();
2361269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE(msg->GetByteString(STUN_ATTR_USE_CANDIDATE) != NULL);
2362269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ch1.Stop();
2363269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
2364269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2365269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// This test case verifies that the CONTROLLING port does not time out.
2366269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestControllingNoTimeout) {
2367269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  UDPPort* port1 = CreateUdpPort(kLocalAddr1);
2368269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ConnectToSignalDestroyed(port1);
2369269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  port1->set_timeout_delay(10);  // milliseconds
2370269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
2371269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  port1->SetIceTiebreaker(kTiebreaker1);
2372269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2373269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  UDPPort* port2 = CreateUdpPort(kLocalAddr2);
2374269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
2375269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  port2->SetIceTiebreaker(kTiebreaker2);
2376269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2377269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Set up channels and ensure both ports will be deleted.
23781eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  TestChannel ch1(port1);
23791eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  TestChannel ch2(port2);
2380269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2381269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Simulate a connection that succeeds, and then is destroyed.
2382be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh  StartConnectAndStopChannels(&ch1, &ch2);
2383269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2384269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // After the connection is destroyed, the port should not be destroyed.
2385269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  rtc::Thread::Current()->ProcessMessages(kTimeout);
2386269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_FALSE(destroyed());
2387269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
2388269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2389269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// This test case verifies that the CONTROLLED port does time out, but only
2390269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org// after connectivity is lost.
2391269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.orgTEST_F(PortTest, TestControlledTimeout) {
2392269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  UDPPort* port1 = CreateUdpPort(kLocalAddr1);
2393269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
2394269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  port1->SetIceTiebreaker(kTiebreaker1);
2395269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2396269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  UDPPort* port2 = CreateUdpPort(kLocalAddr2);
2397269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  ConnectToSignalDestroyed(port2);
2398269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  port2->set_timeout_delay(10);  // milliseconds
2399269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
2400269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  port2->SetIceTiebreaker(kTiebreaker2);
2401269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2402269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // The connection must not be destroyed before a connection is attempted.
2403269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_FALSE(destroyed());
2404269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2405269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  port1->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
2406269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  port2->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
2407269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2408269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Set up channels and ensure both ports will be deleted.
24091eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  TestChannel ch1(port1);
24101eb87c7d94916a6e5641bfbbc8df37527712e4caGuo-wei Shieh  TestChannel ch2(port2);
2411269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2412269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // Simulate a connection that succeeds, and then is destroyed.
2413be508a1d3634ce63b64cd740c44600453e3c3a6bGuo-wei Shieh  StartConnectAndStopChannels(&ch1, &ch2);
2414269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org
2415269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  // The controlled port should be destroyed after 10 milliseconds.
2416269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org  EXPECT_TRUE_WAIT(destroyed(), kTimeout);
2417269fb4bc90b79bebbb8311da0110ccd6803fd0a8henrike@webrtc.org}
2418d0b3143f0e37f5f5e0578e88cf740dd839b50c24honghaiz
2419d0b3143f0e37f5f5e0578e88cf740dd839b50c24honghaiz// This test case verifies that if the role of a port changes from controlled
2420d0b3143f0e37f5f5e0578e88cf740dd839b50c24honghaiz// to controlling after all connections fail, the port will not be destroyed.
2421d0b3143f0e37f5f5e0578e88cf740dd839b50c24honghaizTEST_F(PortTest, TestControlledToControllingNotDestroyed) {
2422d0b3143f0e37f5f5e0578e88cf740dd839b50c24honghaiz  UDPPort* port1 = CreateUdpPort(kLocalAddr1);
2423d0b3143f0e37f5f5e0578e88cf740dd839b50c24honghaiz  port1->SetIceRole(cricket::ICEROLE_CONTROLLING);
2424d0b3143f0e37f5f5e0578e88cf740dd839b50c24honghaiz  port1->SetIceTiebreaker(kTiebreaker1);
2425d0b3143f0e37f5f5e0578e88cf740dd839b50c24honghaiz
2426d0b3143f0e37f5f5e0578e88cf740dd839b50c24honghaiz  UDPPort* port2 = CreateUdpPort(kLocalAddr2);
2427d0b3143f0e37f5f5e0578e88cf740dd839b50c24honghaiz  ConnectToSignalDestroyed(port2);
2428d0b3143f0e37f5f5e0578e88cf740dd839b50c24honghaiz  port2->set_timeout_delay(10);  // milliseconds
2429d0b3143f0e37f5f5e0578e88cf740dd839b50c24honghaiz  port2->SetIceRole(cricket::ICEROLE_CONTROLLED);
2430d0b3143f0e37f5f5e0578e88cf740dd839b50c24honghaiz  port2->SetIceTiebreaker(kTiebreaker2);
2431d0b3143f0e37f5f5e0578e88cf740dd839b50c24honghaiz
2432d0b3143f0e37f5f5e0578e88cf740dd839b50c24honghaiz  // The connection must not be destroyed before a connection is attempted.
2433d0b3143f0e37f5f5e0578e88cf740dd839b50c24honghaiz  EXPECT_FALSE(destroyed());
2434d0b3143f0e37f5f5e0578e88cf740dd839b50c24honghaiz
2435d0b3143f0e37f5f5e0578e88cf740dd839b50c24honghaiz  port1->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
2436d0b3143f0e37f5f5e0578e88cf740dd839b50c24honghaiz  port2->set_component(cricket::ICE_CANDIDATE_COMPONENT_DEFAULT);
2437d0b3143f0e37f5f5e0578e88cf740dd839b50c24honghaiz
2438d0b3143f0e37f5f5e0578e88cf740dd839b50c24honghaiz  // Set up channels and ensure both ports will be deleted.
2439d0b3143f0e37f5f5e0578e88cf740dd839b50c24honghaiz  TestChannel ch1(port1);
2440d0b3143f0e37f5f5e0578e88cf740dd839b50c24honghaiz  TestChannel ch2(port2);
2441d0b3143f0e37f5f5e0578e88cf740dd839b50c24honghaiz
2442d0b3143f0e37f5f5e0578e88cf740dd839b50c24honghaiz  // Simulate a connection that succeeds, and then is destroyed.
2443d0b3143f0e37f5f5e0578e88cf740dd839b50c24honghaiz  StartConnectAndStopChannels(&ch1, &ch2);
2444d0b3143f0e37f5f5e0578e88cf740dd839b50c24honghaiz  // Switch the role after all connections are destroyed.
2445d0b3143f0e37f5f5e0578e88cf740dd839b50c24honghaiz  EXPECT_TRUE_WAIT(ch2.conn() == nullptr, kTimeout);
2446d0b3143f0e37f5f5e0578e88cf740dd839b50c24honghaiz  port1->SetIceRole(cricket::ICEROLE_CONTROLLED);
2447d0b3143f0e37f5f5e0578e88cf740dd839b50c24honghaiz  port2->SetIceRole(cricket::ICEROLE_CONTROLLING);
2448d0b3143f0e37f5f5e0578e88cf740dd839b50c24honghaiz
2449d0b3143f0e37f5f5e0578e88cf740dd839b50c24honghaiz  // After the connection is destroyed, the port should not be destroyed.
2450d0b3143f0e37f5f5e0578e88cf740dd839b50c24honghaiz  rtc::Thread::Current()->ProcessMessages(kTimeout);
2451d0b3143f0e37f5f5e0578e88cf740dd839b50c24honghaiz  EXPECT_FALSE(destroyed());
2452d0b3143f0e37f5f5e0578e88cf740dd839b50c24honghaiz}
2453