1f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org/*
2f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  Copyright 2007 The WebRTC Project Authors. All rights reserved.
3f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *
4f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  Use of this source code is governed by a BSD-style license
5f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  that can be found in the LICENSE file in the root of the source
6f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  tree. An additional intellectual property rights grant can be found
7f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  in the file PATENTS.  All contributing project authors may
8f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org */
10f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
11f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/socket_unittest.h"
12f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
135237aaf243d29732f59557361b7a993c0a18cf0etfarina#include "webrtc/base/arraysize.h"
14f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/asyncudpsocket.h"
15f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/gunit.h"
16f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/nethelpers.h"
17f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/socketserver.h"
18f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/testclient.h"
19f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/testutils.h"
20f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/thread.h"
21f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
22f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgnamespace rtc {
23f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
24f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#define MAYBE_SKIP_IPV6                             \
25f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (!HasIPv6Enabled()) {                          \
26f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    LOG(LS_INFO) << "No IPv6... skipping";          \
27f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return;                                         \
28f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
29f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
30f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
31f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::TestConnectIPv4() {
32f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ConnectInternal(kIPv4Loopback);
33f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
34f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
35f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::TestConnectIPv6() {
36f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  MAYBE_SKIP_IPV6;
37f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ConnectInternal(kIPv6Loopback);
38f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
39f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
40f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::TestConnectWithDnsLookupIPv4() {
41f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ConnectWithDnsLookupInternal(kIPv4Loopback, "localhost");
42f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
43f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
44f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::TestConnectWithDnsLookupIPv6() {
45f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // TODO: Enable this when DNS resolution supports IPv6.
46f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  LOG(LS_INFO) << "Skipping IPv6 DNS test";
47f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // ConnectWithDnsLookupInternal(kIPv6Loopback, "localhost6");
48f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
49f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
50f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::TestConnectFailIPv4() {
51f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ConnectFailInternal(kIPv4Loopback);
52f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
53f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
54f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::TestConnectFailIPv6() {
55f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  MAYBE_SKIP_IPV6;
56f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ConnectFailInternal(kIPv6Loopback);
57f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
58f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
59f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::TestConnectWithDnsLookupFailIPv4() {
60f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ConnectWithDnsLookupFailInternal(kIPv4Loopback);
61f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
62f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
63f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::TestConnectWithDnsLookupFailIPv6() {
64f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  MAYBE_SKIP_IPV6;
65f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ConnectWithDnsLookupFailInternal(kIPv6Loopback);
66f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
67f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
68f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::TestConnectWithClosedSocketIPv4() {
69f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ConnectWithClosedSocketInternal(kIPv4Loopback);
70f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
71f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
72f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::TestConnectWithClosedSocketIPv6() {
73f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  MAYBE_SKIP_IPV6;
74f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ConnectWithClosedSocketInternal(kIPv6Loopback);
75f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
76f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
77f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::TestConnectWhileNotClosedIPv4() {
78f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ConnectWhileNotClosedInternal(kIPv4Loopback);
79f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
80f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
81f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::TestConnectWhileNotClosedIPv6() {
82f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  MAYBE_SKIP_IPV6;
83f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ConnectWhileNotClosedInternal(kIPv6Loopback);
84f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
85f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
86f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::TestServerCloseDuringConnectIPv4() {
87f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ServerCloseDuringConnectInternal(kIPv4Loopback);
88f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
89f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
90f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::TestServerCloseDuringConnectIPv6() {
91f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  MAYBE_SKIP_IPV6;
92f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ServerCloseDuringConnectInternal(kIPv6Loopback);
93f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
94f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
95f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::TestClientCloseDuringConnectIPv4() {
96f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ClientCloseDuringConnectInternal(kIPv4Loopback);
97f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
98f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
99f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::TestClientCloseDuringConnectIPv6() {
100f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  MAYBE_SKIP_IPV6;
101f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ClientCloseDuringConnectInternal(kIPv6Loopback);
102f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
103f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
104f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::TestServerCloseIPv4() {
105f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ServerCloseInternal(kIPv4Loopback);
106f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
107f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
108f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::TestServerCloseIPv6() {
109f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  MAYBE_SKIP_IPV6;
110f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ServerCloseInternal(kIPv6Loopback);
111f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
112f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
113f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::TestCloseInClosedCallbackIPv4() {
114f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  CloseInClosedCallbackInternal(kIPv4Loopback);
115f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
116f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
117f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::TestCloseInClosedCallbackIPv6() {
118f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  MAYBE_SKIP_IPV6;
119f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  CloseInClosedCallbackInternal(kIPv6Loopback);
120f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
121f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
122f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::TestSocketServerWaitIPv4() {
123f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SocketServerWaitInternal(kIPv4Loopback);
124f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
125f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
126f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::TestSocketServerWaitIPv6() {
127f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  MAYBE_SKIP_IPV6;
128f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SocketServerWaitInternal(kIPv6Loopback);
129f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
130f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
131f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::TestTcpIPv4() {
132f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  TcpInternal(kIPv4Loopback);
133f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
134f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
135f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::TestTcpIPv6() {
136f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  MAYBE_SKIP_IPV6;
137f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  TcpInternal(kIPv6Loopback);
138f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
139f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
140f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::TestSingleFlowControlCallbackIPv4() {
141f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SingleFlowControlCallbackInternal(kIPv4Loopback);
142f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
143f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
144f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::TestSingleFlowControlCallbackIPv6() {
145f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  MAYBE_SKIP_IPV6;
146f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SingleFlowControlCallbackInternal(kIPv6Loopback);
147f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
148f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
149f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::TestUdpIPv4() {
150f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  UdpInternal(kIPv4Loopback);
151f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
152f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
153f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::TestUdpIPv6() {
154f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  MAYBE_SKIP_IPV6;
155f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  UdpInternal(kIPv6Loopback);
156f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
157f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
158f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::TestUdpReadyToSendIPv4() {
159f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#if !defined(WEBRTC_MAC)
160f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // TODO(ronghuawu): Enable this test on mac/ios.
161f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  UdpReadyToSend(kIPv4Loopback);
162f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif
163f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
164f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
165f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::TestUdpReadyToSendIPv6() {
166f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#if defined(WEBRTC_WIN)
167f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // TODO(ronghuawu): Enable this test (currently flakey) on mac and linux.
168f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  MAYBE_SKIP_IPV6;
169f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  UdpReadyToSend(kIPv6Loopback);
170f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif
171f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
172f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
173f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::TestGetSetOptionsIPv4() {
174f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  GetSetOptionsInternal(kIPv4Loopback);
175f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
176f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
177f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::TestGetSetOptionsIPv6() {
178f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  MAYBE_SKIP_IPV6;
179f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  GetSetOptionsInternal(kIPv6Loopback);
180f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
181f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
182f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// For unbound sockets, GetLocalAddress / GetRemoteAddress return AF_UNSPEC
183f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// values on Windows, but an empty address of the same family on Linux/MacOS X.
184f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgbool IsUnspecOrEmptyIP(const IPAddress& address) {
185f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#if !defined(WEBRTC_WIN)
186f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return IPIsAny(address);
187f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#else
188f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return address.family() == AF_UNSPEC;
189f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif
190f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
191f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
192f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::ConnectInternal(const IPAddress& loopback) {
193f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  testing::StreamSink sink;
194f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SocketAddress accept_addr;
195f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
196f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Create client.
197f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<AsyncSocket> client(ss_->CreateAsyncSocket(loopback.family(),
198f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                                        SOCK_STREAM));
199f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  sink.Monitor(client.get());
200f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CLOSED, client->GetState());
201f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_PRED1(IsUnspecOrEmptyIP, client->GetLocalAddress().ipaddr());
202f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
203f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Create server and listen.
204f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<AsyncSocket> server(
205f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
206f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  sink.Monitor(server.get());
207f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
208f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, server->Listen(5));
209f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CONNECTING, server->GetState());
210f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
211f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Ensure no pending server connections, since we haven't done anything yet.
212f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ));
213f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE(NULL == server->Accept(&accept_addr));
214f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE(accept_addr.IsNil());
215f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
216f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Attempt connect to listening socket.
217f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
218f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_FALSE(client->GetLocalAddress().IsNil());
219f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_NE(server->GetLocalAddress(), client->GetLocalAddress());
220f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
221f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Client is connecting, outcome not yet determined.
222f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
223f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN));
224f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
225f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
226f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Server has pending connection, accept it.
227f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
228f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
229f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT_TRUE(accepted);
230f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_FALSE(accept_addr.IsNil());
231f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
232f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
233f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Connected from server perspective, check the addresses are correct.
234f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
235f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
236f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
237f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
238f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Connected from client perspective, check the addresses are correct.
239f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
240f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
241f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
242f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
243f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
244f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
245f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
246f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::ConnectWithDnsLookupInternal(const IPAddress& loopback,
247f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                              const std::string& host) {
248f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  testing::StreamSink sink;
249f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SocketAddress accept_addr;
250f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
251f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Create client.
252f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<AsyncSocket> client(
253f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
254f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  sink.Monitor(client.get());
255f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
256f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Create server and listen.
257f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<AsyncSocket> server(
258f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
259f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  sink.Monitor(server.get());
260f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
261f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, server->Listen(5));
262f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
263f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Attempt connect to listening socket.
264f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SocketAddress dns_addr(server->GetLocalAddress());
265f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  dns_addr.SetIP(host);
266f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, client->Connect(dns_addr));
267f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // TODO: Bind when doing DNS lookup.
268f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  //EXPECT_NE(kEmptyAddr, client->GetLocalAddress());  // Implicit Bind
269f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
270f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Client is connecting, outcome not yet determined.
271f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
272f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN));
273f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
274f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
275f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Server has pending connection, accept it.
276f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
277f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
278f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT_TRUE(accepted);
279f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_FALSE(accept_addr.IsNil());
280f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
281f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
282f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Connected from server perspective, check the addresses are correct.
283f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
284f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
285f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
286f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
287f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Connected from client perspective, check the addresses are correct.
288f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
289f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
290f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
291f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
292f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
293f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
294f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
295f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::ConnectFailInternal(const IPAddress& loopback) {
296f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  testing::StreamSink sink;
297f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SocketAddress accept_addr;
298f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
299f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Create client.
300f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<AsyncSocket> client(
301f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
302f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  sink.Monitor(client.get());
303f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
304f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Create server, but don't listen yet.
305f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<AsyncSocket> server(
306f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
307f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  sink.Monitor(server.get());
308f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
309f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
310f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Attempt connect to a non-existent socket.
311f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // We don't connect to the server socket created above, since on
312f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // MacOS it takes about 75 seconds to get back an error!
313f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SocketAddress bogus_addr(loopback, 65535);
314f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, client->Connect(bogus_addr));
315f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
316f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Wait for connection to fail (ECONNREFUSED).
317f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
318f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN));
319f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_ERROR));
320f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE(client->GetRemoteAddress().IsNil());
321f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
322f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Should be no pending server connections.
323f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ));
324f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE(NULL == server->Accept(&accept_addr));
325f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(IPAddress(), accept_addr.ipaddr());
326f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
327f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
328f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::ConnectWithDnsLookupFailInternal(const IPAddress& loopback) {
329f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  testing::StreamSink sink;
330f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SocketAddress accept_addr;
331f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
332f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Create client.
333f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<AsyncSocket> client(
334f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
335f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  sink.Monitor(client.get());
336f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
337f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Create server, but don't listen yet.
338f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<AsyncSocket> server(
339f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
340f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  sink.Monitor(server.get());
341f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
342f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
343f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Attempt connect to a non-existent host.
344f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // We don't connect to the server socket created above, since on
345f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // MacOS it takes about 75 seconds to get back an error!
346f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SocketAddress bogus_dns_addr("not-a-real-hostname", 65535);
347f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, client->Connect(bogus_dns_addr));
348f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
349f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Wait for connection to fail (EHOSTNOTFOUND).
350f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  bool dns_lookup_finished = false;
351f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  WAIT_(client->GetState() == AsyncSocket::CS_CLOSED, kTimeout,
352f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        dns_lookup_finished);
353f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (!dns_lookup_finished) {
354f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    LOG(LS_WARNING) << "Skipping test; DNS resolution took longer than 5 "
355f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                    << "seconds.";
356f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return;
357f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
358f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
359f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
360f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN));
361f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_ERROR));
362f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE(client->GetRemoteAddress().IsNil());
363f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Should be no pending server connections.
364f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ));
365f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE(NULL == server->Accept(&accept_addr));
366f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE(accept_addr.IsNil());
367f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
368f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
369f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::ConnectWithClosedSocketInternal(const IPAddress& loopback) {
370f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Create server and listen.
371f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<AsyncSocket> server(
372f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
373f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
374f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, server->Listen(5));
375f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
376f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Create a client and put in to CS_CLOSED state.
377f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<AsyncSocket> client(
378f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
379f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, client->Close());
380f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CLOSED, client->GetState());
381f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
382f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Connect() should reinitialize the socket, and put it in to CS_CONNECTING.
383f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
384f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
385f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
386f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
387f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::ConnectWhileNotClosedInternal(const IPAddress& loopback) {
388f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Create server and listen.
389f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  testing::StreamSink sink;
390f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<AsyncSocket> server(
391f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
392f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  sink.Monitor(server.get());
393f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
394f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, server->Listen(5));
395f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Create client, connect.
396f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<AsyncSocket> client(
397f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
398f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
399f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
400f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Try to connect again. Should fail, but not interfere with original attempt.
401f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(SOCKET_ERROR,
402f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org            client->Connect(SocketAddress(server->GetLocalAddress())));
403f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
404f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Accept the original connection.
405f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SocketAddress accept_addr;
406f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
407f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
408f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT_TRUE(accepted);
409f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_FALSE(accept_addr.IsNil());
410f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
411f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Check the states and addresses.
412f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
413f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
414f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
415f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
416f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
417f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
418f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
419f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Try to connect again, to an unresolved hostname.
420f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Shouldn't break anything.
421f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(SOCKET_ERROR,
422f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org            client->Connect(SocketAddress("localhost",
423f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                          server->GetLocalAddress().port())));
424f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
425f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
426f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
427f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
428f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
429f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
430f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::ServerCloseDuringConnectInternal(const IPAddress& loopback) {
431f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  testing::StreamSink sink;
432f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
433f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Create client.
434f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<AsyncSocket> client(
435f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
436f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  sink.Monitor(client.get());
437f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
438f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Create server and listen.
439f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<AsyncSocket> server(
440f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
441f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  sink.Monitor(server.get());
442f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
443f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, server->Listen(5));
444f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
445f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Attempt connect to listening socket.
446f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
447f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
448f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Close down the server while the socket is in the accept queue.
449f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE_WAIT(sink.Check(server.get(), testing::SSE_READ), kTimeout);
450f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  server->Close();
451f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
452f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // This should fail the connection for the client. Clean up.
453f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
454f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_ERROR));
455f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  client->Close();
456f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
457f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
458f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::ClientCloseDuringConnectInternal(const IPAddress& loopback) {
459f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  testing::StreamSink sink;
460f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SocketAddress accept_addr;
461f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
462f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Create client.
463f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<AsyncSocket> client(
464f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
465f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  sink.Monitor(client.get());
466f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
467f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Create server and listen.
468f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<AsyncSocket> server(
469f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
470f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  sink.Monitor(server.get());
471f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
472f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, server->Listen(5));
473f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
474f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Attempt connect to listening socket.
475f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
476f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
477f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Close down the client while the socket is in the accept queue.
478f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE_WAIT(sink.Check(server.get(), testing::SSE_READ), kTimeout);
479f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  client->Close();
480f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
481f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // The connection should still be able to be accepted.
482f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
483f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT_TRUE(accepted);
484f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  sink.Monitor(accepted.get());
485f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
486f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
487f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // The accepted socket should then close (possibly with err, timing-related)
488f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, accepted->GetState(), kTimeout);
489f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE(sink.Check(accepted.get(), testing::SSE_CLOSE) ||
490f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org              sink.Check(accepted.get(), testing::SSE_ERROR));
491f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
492f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // The client should not get a close event.
493f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
494f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
495f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
496f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::ServerCloseInternal(const IPAddress& loopback) {
497f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  testing::StreamSink sink;
498f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SocketAddress accept_addr;
499f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
500f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Create client.
501f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<AsyncSocket> client(
502f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
503f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  sink.Monitor(client.get());
504f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
505f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Create server and listen.
506f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<AsyncSocket> server(
507f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
508f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  sink.Monitor(server.get());
509f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
510f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, server->Listen(5));
511f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
512f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Attempt connection.
513f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
514f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
515f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Accept connection.
516f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
517f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
518f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT_TRUE(accepted);
519f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  sink.Monitor(accepted.get());
520f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
521f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Both sides are now connected.
522f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
523f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
524f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
525f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
526f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
527f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Send data to the client, and then close the connection.
528f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(1, accepted->Send("a", 1));
529f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  accepted->Close();
530f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CLOSED, accepted->GetState());
531f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
532f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Expect that the client is notified, and has not yet closed.
533f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE_WAIT(sink.Check(client.get(), testing::SSE_READ), kTimeout);
534f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
535f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
536f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
537f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Ensure the data can be read.
538f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  char buffer[10];
539f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(1, client->Recv(buffer, sizeof(buffer)));
540f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ('a', buffer[0]);
541f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
542f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Now we should close, but the remote address will remain.
543f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
544f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_CLOSE));
545f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_FALSE(client->GetRemoteAddress().IsAnyIP());
546f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
547f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // The closer should not get a close signal.
548f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_CLOSE));
549f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE(accepted->GetRemoteAddress().IsNil());
550f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
551f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // And the closee should only get a single signal.
552f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  Thread::Current()->ProcessMessages(0);
553f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
554f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
555f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Close down the client and ensure all is good.
556f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  client->Close();
557f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
558f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE(client->GetRemoteAddress().IsNil());
559f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
560f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
561f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgclass SocketCloser : public sigslot::has_slots<> {
562f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org public:
563f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  void OnClose(AsyncSocket* socket, int error) {
564f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    socket->Close();  // Deleting here would blow up the vector of handlers
565f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                      // for the socket's signal.
566f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
567f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org};
568f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
569f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::CloseInClosedCallbackInternal(const IPAddress& loopback) {
570f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  testing::StreamSink sink;
571f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SocketCloser closer;
572f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SocketAddress accept_addr;
573f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
574f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Create client.
575f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<AsyncSocket> client(
576f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
577f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  sink.Monitor(client.get());
578f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  client->SignalCloseEvent.connect(&closer, &SocketCloser::OnClose);
579f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
580f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Create server and listen.
581f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<AsyncSocket> server(
582f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
583f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  sink.Monitor(server.get());
584f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
585f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, server->Listen(5));
586f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
587f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Attempt connection.
588f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
589f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
590f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Accept connection.
591f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
592f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
593f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT_TRUE(accepted);
594f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  sink.Monitor(accepted.get());
595f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
596f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Both sides are now connected.
597f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
598f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
599f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
600f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
601f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
602f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Send data to the client, and then close the connection.
603f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  accepted->Close();
604f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CLOSED, accepted->GetState());
605f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
606f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Expect that the client is notified, and has not yet closed.
607f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
608f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
609f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
610f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Now we should be closed and invalidated
611f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
612f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_CLOSE));
613f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE(Socket::CS_CLOSED == client->GetState());
614f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
615f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
616f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgclass Sleeper : public MessageHandler {
617f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org public:
618f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  Sleeper() {}
619f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  void OnMessage(Message* msg) {
620f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    Thread::Current()->SleepMs(500);
621f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
622f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org};
623f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
624f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::SocketServerWaitInternal(const IPAddress& loopback) {
625f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  testing::StreamSink sink;
626f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SocketAddress accept_addr;
627f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
628f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Create & connect server and client sockets.
629f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<AsyncSocket> client(
630f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
631f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<AsyncSocket> server(
632f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
633f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  sink.Monitor(client.get());
634f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  sink.Monitor(server.get());
635f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
636f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, server->Listen(5));
637f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
638f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
639f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
640f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
641f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
642f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT_TRUE(accepted);
643f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  sink.Monitor(accepted.get());
644f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
645f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
646f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
647f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
648f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
649f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
650f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
651f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
652f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
653f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
654f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Do an i/o operation, triggering an eventual callback.
655f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_READ));
656f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  char buf[1024] = {0};
657f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
658f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(1024, client->Send(buf, 1024));
659f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_READ));
660f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
661f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Shouldn't signal when blocked in a thread Send, where process_io is false.
662f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<Thread> thread(new Thread());
663f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  thread->Start();
664f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  Sleeper sleeper;
665f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  TypedMessageData<AsyncSocket*> data(client.get());
666f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  thread->Send(&sleeper, 0, &data);
667f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_READ));
668f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
669f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // But should signal when process_io is true.
670f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE_WAIT((sink.Check(accepted.get(), testing::SSE_READ)), kTimeout);
671f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_LT(0, accepted->Recv(buf, 1024));
672f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
673f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
674f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::TcpInternal(const IPAddress& loopback) {
675f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  testing::StreamSink sink;
676f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SocketAddress accept_addr;
677f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
678f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Create test data.
679f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  const size_t kDataSize = 1024 * 1024;
680f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<char[]> send_buffer(new char[kDataSize]);
681f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<char[]> recv_buffer(new char[kDataSize]);
682f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  size_t send_pos = 0, recv_pos = 0;
683f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  for (size_t i = 0; i < kDataSize; ++i) {
684f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    send_buffer[i] = static_cast<char>(i % 256);
685f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    recv_buffer[i] = 0;
686f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
687f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
688f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Create client.
689f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<AsyncSocket> client(
690f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
691f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  sink.Monitor(client.get());
692f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
693f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Create server and listen.
694f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<AsyncSocket> server(
695f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
696f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  sink.Monitor(server.get());
697f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
698f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, server->Listen(5));
699f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
700f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Attempt connection.
701f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
702f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
703f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Accept connection.
704f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
705f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
706f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT_TRUE(accepted);
707f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  sink.Monitor(accepted.get());
708f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
709f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Both sides are now connected.
710f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
711f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
712f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
713f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
714f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
715f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Send and receive a bunch of data.
716f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  bool send_waiting_for_writability = false;
717f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  bool send_expect_success = true;
718f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  bool recv_waiting_for_readability = true;
719f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  bool recv_expect_success = false;
720f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  int data_in_flight = 0;
721f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  while (recv_pos < kDataSize) {
722f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // Send as much as we can if we've been cleared to send.
723f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    while (!send_waiting_for_writability && send_pos < kDataSize) {
724f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      int tosend = static_cast<int>(kDataSize - send_pos);
725f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      int sent = accepted->Send(send_buffer.get() + send_pos, tosend);
726f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      if (send_expect_success) {
727f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        // The first Send() after connecting or getting writability should
728f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        // succeed and send some data.
729f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        EXPECT_GT(sent, 0);
730f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        send_expect_success = false;
731f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      }
732f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      if (sent >= 0) {
733f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        EXPECT_LE(sent, tosend);
734f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        send_pos += sent;
735f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        data_in_flight += sent;
736f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      } else {
737f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        ASSERT_TRUE(accepted->IsBlocking());
738f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        send_waiting_for_writability = true;
739f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      }
740f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    }
741f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
742f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // Read all the sent data.
743f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    while (data_in_flight > 0) {
744f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      if (recv_waiting_for_readability) {
745f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        // Wait until data is available.
746f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        EXPECT_TRUE_WAIT(sink.Check(client.get(), testing::SSE_READ), kTimeout);
747f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        recv_waiting_for_readability = false;
748f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        recv_expect_success = true;
749f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      }
750f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
751f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      // Receive as much as we can get in a single recv call.
752f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      int rcvd = client->Recv(recv_buffer.get() + recv_pos,
753f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                              kDataSize - recv_pos);
754f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
755f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      if (recv_expect_success) {
756f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        // The first Recv() after getting readability should succeed and receive
757f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        // some data.
758f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        // TODO: The following line is disabled due to flakey pulse
759f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        //     builds.  Re-enable if/when possible.
760f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        // EXPECT_GT(rcvd, 0);
761f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        recv_expect_success = false;
762f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      }
763f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      if (rcvd >= 0) {
764f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        EXPECT_LE(rcvd, data_in_flight);
765f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        recv_pos += rcvd;
766f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        data_in_flight -= rcvd;
767f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      } else {
768f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        ASSERT_TRUE(client->IsBlocking());
769f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        recv_waiting_for_readability = true;
770f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      }
771f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    }
772f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
773f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // Once all that we've sent has been rcvd, expect to be able to send again.
774f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (send_waiting_for_writability) {
775f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      EXPECT_TRUE_WAIT(sink.Check(accepted.get(), testing::SSE_WRITE),
776f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                       kTimeout);
777f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      send_waiting_for_writability = false;
778f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      send_expect_success = true;
779f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    }
780f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
781f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
782f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // The received data matches the sent data.
783f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(kDataSize, send_pos);
784f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(kDataSize, recv_pos);
785f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, memcmp(recv_buffer.get(), send_buffer.get(), kDataSize));
786f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
787f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Close down.
788f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  accepted->Close();
789f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
790f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_CLOSE));
791f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  client->Close();
792f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
793f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
794f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::SingleFlowControlCallbackInternal(const IPAddress& loopback) {
795f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  testing::StreamSink sink;
796f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SocketAddress accept_addr;
797f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
798f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Create client.
799f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<AsyncSocket> client(
800f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
801f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  sink.Monitor(client.get());
802f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
803f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Create server and listen.
804f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<AsyncSocket> server(
805f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
806f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  sink.Monitor(server.get());
807f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
808f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, server->Listen(5));
809f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
810f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Attempt connection.
811f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
812f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
813f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Accept connection.
814f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
815f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
816f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT_TRUE(accepted);
817f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  sink.Monitor(accepted.get());
818f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
819f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Both sides are now connected.
820f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
821f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
822f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
823f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
824f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
825f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Expect a writable callback from the connect.
826f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE_WAIT(sink.Check(accepted.get(), testing::SSE_WRITE), kTimeout);
827f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
828f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Fill the socket buffer.
829f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  char buf[1024 * 16] = {0};
830f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  int sends = 0;
8315237aaf243d29732f59557361b7a993c0a18cf0etfarina  while (++sends && accepted->Send(&buf, arraysize(buf)) != -1) {}
832f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE(accepted->IsBlocking());
833f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
834f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Wait until data is available.
835f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE_WAIT(sink.Check(client.get(), testing::SSE_READ), kTimeout);
836f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
837f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Pull data.
838f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  for (int i = 0; i < sends; ++i) {
8395237aaf243d29732f59557361b7a993c0a18cf0etfarina    client->Recv(buf, arraysize(buf));
840f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
841f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
842f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Expect at least one additional writable callback.
843f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE_WAIT(sink.Check(accepted.get(), testing::SSE_WRITE), kTimeout);
844f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
845f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Adding data in response to the writeable callback shouldn't cause infinite
846f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // callbacks.
847f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  int extras = 0;
848f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  for (int i = 0; i < 100; ++i) {
8495237aaf243d29732f59557361b7a993c0a18cf0etfarina    accepted->Send(&buf, arraysize(buf));
850f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    rtc::Thread::Current()->ProcessMessages(1);
851f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (sink.Check(accepted.get(), testing::SSE_WRITE)) {
852f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      extras++;
853f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    }
854f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
855f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_LT(extras, 2);
856f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
857f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Close down.
858f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  accepted->Close();
859f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  client->Close();
860f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
861f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
862f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::UdpInternal(const IPAddress& loopback) {
863f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
864f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Test basic bind and connect behavior.
865f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  AsyncSocket* socket =
866f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM);
867f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CLOSED, socket->GetState());
868f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, socket->Bind(SocketAddress(loopback, 0)));
869f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SocketAddress addr1 = socket->GetLocalAddress();
870f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(0, socket->Connect(addr1));
871f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CONNECTED, socket->GetState());
872f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  socket->Close();
873f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CLOSED, socket->GetState());
874f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  delete socket;
875f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
876f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Test send/receive behavior.
877f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<TestClient> client1(
878f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      new TestClient(AsyncUDPSocket::Create(ss_, addr1)));
879f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<TestClient> client2(
880f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      new TestClient(AsyncUDPSocket::Create(ss_, empty)));
881f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
882f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SocketAddress addr2;
883f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
884f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr2));
885f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
886f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SocketAddress addr3;
887f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr2));
888f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr3));
889f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(addr3, addr1);
890f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // TODO: figure out what the intent is here
891f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  for (int i = 0; i < 10; ++i) {
892f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    client2.reset(new TestClient(AsyncUDPSocket::Create(ss_, empty)));
893f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
894f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    SocketAddress addr4;
895f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
896f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr4));
897f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    EXPECT_EQ(addr4.ipaddr(), addr2.ipaddr());
898f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
899f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    SocketAddress addr5;
900f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr4));
901f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr5));
902f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    EXPECT_EQ(addr5, addr1);
903f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
904f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    addr2 = addr4;
905f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
906f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
907f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
908f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::UdpReadyToSend(const IPAddress& loopback) {
909f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
910f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // RFC 5737 - The blocks 192.0.2.0/24 (TEST-NET-1) ... are provided for use in
911f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // documentation.
912f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // RFC 3849 - 2001:DB8::/32 as a documentation-only prefix.
913f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  std::string dest = (loopback.family() == AF_INET6) ?
914f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      "2001:db8::1" : "192.0.2.0";
915f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SocketAddress test_addr(dest, 2345);
916f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
917f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Test send
918f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  scoped_ptr<TestClient> client(
919f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      new TestClient(AsyncUDPSocket::Create(ss_, empty)));
920f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  int test_packet_size = 1200;
921f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  rtc::scoped_ptr<char[]> test_packet(new char[test_packet_size]);
922f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Init the test packet just to avoid memcheck warning.
923f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  memset(test_packet.get(), 0, test_packet_size);
924f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Set the send buffer size to the same size as the test packet to have a
925f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // better chance to get EWOULDBLOCK.
926f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  int send_buffer_size = test_packet_size;
927f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
928f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  send_buffer_size /= 2;
929f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif
930f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  client->SetOption(rtc::Socket::OPT_SNDBUF, send_buffer_size);
931f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
932f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  int error = 0;
9330c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  uint32_t start_ms = Time();
934f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  int sent_packet_num = 0;
935f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  int expected_error = EWOULDBLOCK;
936f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  while (start_ms + kTimeout > Time()) {
937f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    int ret = client->SendTo(test_packet.get(), test_packet_size, test_addr);
938f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ++sent_packet_num;
939f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (ret != test_packet_size) {
940f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      error = client->GetError();
941f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      if (error == expected_error) {
942f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        LOG(LS_INFO) << "Got expected error code after sending "
943f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                     << sent_packet_num << " packets.";
944f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        break;
945f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      }
946f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    }
947f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
948f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_EQ(expected_error, error);
949f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_FALSE(client->ready_to_send());
950f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  EXPECT_TRUE_WAIT(client->ready_to_send(), kTimeout);
951f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  LOG(LS_INFO) << "Got SignalReadyToSend";
952f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
953f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
954f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid SocketTest::GetSetOptionsInternal(const IPAddress& loopback) {
955f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  rtc::scoped_ptr<AsyncSocket> socket(
956f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM));
957f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  socket->Bind(SocketAddress(loopback, 0));
958f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
959f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Check SNDBUF/RCVBUF.
960f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  const int desired_size = 12345;
961f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#if defined(WEBRTC_LINUX)
962f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Yes, really.  It's in the kernel source.
963f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  const int expected_size = desired_size * 2;
964f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#else   // !WEBRTC_LINUX
965f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  const int expected_size = desired_size;
966f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif  // !WEBRTC_LINUX
967f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  int recv_size = 0;
968f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  int send_size = 0;
969f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // get the initial sizes
970f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
971f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
972f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // set our desired sizes
973f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT_NE(-1, socket->SetOption(Socket::OPT_RCVBUF, desired_size));
974f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT_NE(-1, socket->SetOption(Socket::OPT_SNDBUF, desired_size));
975f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // get the sizes again
976f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
977f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
978f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // make sure they are right
979f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT_EQ(expected_size, recv_size);
980f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT_EQ(expected_size, send_size);
981f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
982f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Check that we can't set NODELAY on a UDP socket.
983f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  int current_nd, desired_nd = 1;
984f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT_EQ(-1, socket->GetOption(Socket::OPT_NODELAY, &current_nd));
985f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT_EQ(-1, socket->SetOption(Socket::OPT_NODELAY, desired_nd));
986f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
987f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Skip the esimate MTU test for IPv6 for now.
988f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (loopback.family() != AF_INET6) {
989f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // Try estimating MTU.
990f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    rtc::scoped_ptr<AsyncSocket>
991f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        mtu_socket(
992f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org            ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM));
993f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    mtu_socket->Bind(SocketAddress(loopback, 0));
9940c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström    uint16_t mtu;
995f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // should fail until we connect
996f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ASSERT_EQ(-1, mtu_socket->EstimateMTU(&mtu));
997f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    mtu_socket->Connect(SocketAddress(loopback, 0));
998f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#if defined(WEBRTC_WIN)
999f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // now it should succeed
1000f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ASSERT_NE(-1, mtu_socket->EstimateMTU(&mtu));
1001f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ASSERT_GE(mtu, 1492);  // should be at least the 1492 "plateau" on localhost
1002f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
1003f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // except on WEBRTC_MAC && !WEBRTC_IOS, where it's not yet implemented
1004f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ASSERT_EQ(-1, mtu_socket->EstimateMTU(&mtu));
1005f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#else
1006f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // and the behavior seems unpredictable on Linux,
1007f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // failing on the build machine
1008f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // but succeeding on my Ubiquity instance.
1009f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif
1010f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
1011f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
1012f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
1013f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}  // namespace rtc
1014