147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org/*
247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  Copyright 2007 The WebRTC Project Authors. All rights reserved.
347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *
447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  Use of this source code is governed by a BSD-style license
547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  that can be found in the LICENSE file in the root of the source
647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  tree. An additional intellectual property rights grant can be found
747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  in the file PATENTS.  All contributing project authors may
847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org */
1047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/socket_unittest.h"
1247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/asyncudpsocket.h"
1447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/gunit.h"
1547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/nethelpers.h"
1647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/socketserver.h"
1747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/testclient.h"
1847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/testutils.h"
1947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/thread.h"
2047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
2147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgnamespace rtc {
2247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
2347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define MAYBE_SKIP_IPV6                             \
2447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!HasIPv6Enabled()) {                          \
2547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LOG(LS_INFO) << "No IPv6... skipping";          \
2647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return;                                         \
2747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
2847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
2947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
3047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::TestConnectIPv4() {
3147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ConnectInternal(kIPv4Loopback);
3247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
3347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
3447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::TestConnectIPv6() {
3547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  MAYBE_SKIP_IPV6;
3647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ConnectInternal(kIPv6Loopback);
3747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
3847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
3947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::TestConnectWithDnsLookupIPv4() {
4047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ConnectWithDnsLookupInternal(kIPv4Loopback, "localhost");
4147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
4247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
4347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::TestConnectWithDnsLookupIPv6() {
4447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // TODO: Enable this when DNS resolution supports IPv6.
4547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  LOG(LS_INFO) << "Skipping IPv6 DNS test";
4647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // ConnectWithDnsLookupInternal(kIPv6Loopback, "localhost6");
4747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
4847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
4947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::TestConnectFailIPv4() {
5047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ConnectFailInternal(kIPv4Loopback);
5147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
5247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
5347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::TestConnectFailIPv6() {
5447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  MAYBE_SKIP_IPV6;
5547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ConnectFailInternal(kIPv6Loopback);
5647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
5747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
5847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::TestConnectWithDnsLookupFailIPv4() {
5947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ConnectWithDnsLookupFailInternal(kIPv4Loopback);
6047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
6147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
6247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::TestConnectWithDnsLookupFailIPv6() {
6347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  MAYBE_SKIP_IPV6;
6447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ConnectWithDnsLookupFailInternal(kIPv6Loopback);
6547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
6647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
6747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::TestConnectWithClosedSocketIPv4() {
6847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ConnectWithClosedSocketInternal(kIPv4Loopback);
6947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
7047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
7147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::TestConnectWithClosedSocketIPv6() {
7247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  MAYBE_SKIP_IPV6;
7347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ConnectWithClosedSocketInternal(kIPv6Loopback);
7447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
7547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
7647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::TestConnectWhileNotClosedIPv4() {
7747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ConnectWhileNotClosedInternal(kIPv4Loopback);
7847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
7947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
8047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::TestConnectWhileNotClosedIPv6() {
8147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  MAYBE_SKIP_IPV6;
8247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ConnectWhileNotClosedInternal(kIPv6Loopback);
8347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
8447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
8547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::TestServerCloseDuringConnectIPv4() {
8647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ServerCloseDuringConnectInternal(kIPv4Loopback);
8747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
8847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
8947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::TestServerCloseDuringConnectIPv6() {
9047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  MAYBE_SKIP_IPV6;
9147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ServerCloseDuringConnectInternal(kIPv6Loopback);
9247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
9347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
9447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::TestClientCloseDuringConnectIPv4() {
9547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ClientCloseDuringConnectInternal(kIPv4Loopback);
9647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
9747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
9847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::TestClientCloseDuringConnectIPv6() {
9947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  MAYBE_SKIP_IPV6;
10047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ClientCloseDuringConnectInternal(kIPv6Loopback);
10147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
10247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
10347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::TestServerCloseIPv4() {
10447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ServerCloseInternal(kIPv4Loopback);
10547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
10647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
10747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::TestServerCloseIPv6() {
10847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  MAYBE_SKIP_IPV6;
10947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ServerCloseInternal(kIPv6Loopback);
11047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
11147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
11247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::TestCloseInClosedCallbackIPv4() {
11347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CloseInClosedCallbackInternal(kIPv4Loopback);
11447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
11547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
11647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::TestCloseInClosedCallbackIPv6() {
11747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  MAYBE_SKIP_IPV6;
11847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CloseInClosedCallbackInternal(kIPv6Loopback);
11947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
12047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
12147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::TestSocketServerWaitIPv4() {
12247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketServerWaitInternal(kIPv4Loopback);
12347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
12447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
12547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::TestSocketServerWaitIPv6() {
12647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  MAYBE_SKIP_IPV6;
12747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketServerWaitInternal(kIPv6Loopback);
12847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
12947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
13047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::TestTcpIPv4() {
13147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  TcpInternal(kIPv4Loopback);
13247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
13347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
13447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::TestTcpIPv6() {
13547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  MAYBE_SKIP_IPV6;
13647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  TcpInternal(kIPv6Loopback);
13747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
13847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
13947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::TestSingleFlowControlCallbackIPv4() {
14047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SingleFlowControlCallbackInternal(kIPv4Loopback);
14147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
14247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
14347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::TestSingleFlowControlCallbackIPv6() {
14447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  MAYBE_SKIP_IPV6;
14547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SingleFlowControlCallbackInternal(kIPv6Loopback);
14647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
14747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
14847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::TestUdpIPv4() {
14947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  UdpInternal(kIPv4Loopback);
15047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
15147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
15247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::TestUdpIPv6() {
15347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  MAYBE_SKIP_IPV6;
15447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  UdpInternal(kIPv6Loopback);
15547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
15647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
15747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::TestUdpReadyToSendIPv4() {
15847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if !defined(WEBRTC_MAC)
15947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // TODO(ronghuawu): Enable this test on mac/ios.
16047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  UdpReadyToSend(kIPv4Loopback);
16147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif
16247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
16347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
16447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::TestUdpReadyToSendIPv6() {
16547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN)
16647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // TODO(ronghuawu): Enable this test (currently flakey) on mac and linux.
16747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  MAYBE_SKIP_IPV6;
16847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  UdpReadyToSend(kIPv6Loopback);
16947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif
17047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
17147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
17247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::TestGetSetOptionsIPv4() {
17347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  GetSetOptionsInternal(kIPv4Loopback);
17447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
17547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
17647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::TestGetSetOptionsIPv6() {
17747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  MAYBE_SKIP_IPV6;
17847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  GetSetOptionsInternal(kIPv6Loopback);
17947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
18047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
18147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// For unbound sockets, GetLocalAddress / GetRemoteAddress return AF_UNSPEC
18247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// values on Windows, but an empty address of the same family on Linux/MacOS X.
18347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool IsUnspecOrEmptyIP(const IPAddress& address) {
18447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if !defined(WEBRTC_WIN)
18547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return IPIsAny(address);
18647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#else
18747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return address.family() == AF_UNSPEC;
18847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif
18947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
19047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
19147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::ConnectInternal(const IPAddress& loopback) {
19247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  testing::StreamSink sink;
19347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress accept_addr;
19447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
19547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Create client.
19647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<AsyncSocket> client(ss_->CreateAsyncSocket(loopback.family(),
19747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                                        SOCK_STREAM));
19847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sink.Monitor(client.get());
19947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CLOSED, client->GetState());
20047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_PRED1(IsUnspecOrEmptyIP, client->GetLocalAddress().ipaddr());
20147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
20247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Create server and listen.
20347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<AsyncSocket> server(
20447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
20547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sink.Monitor(server.get());
20647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
20747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, server->Listen(5));
20847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CONNECTING, server->GetState());
20947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
21047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Ensure no pending server connections, since we haven't done anything yet.
21147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ));
21247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(NULL == server->Accept(&accept_addr));
21347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(accept_addr.IsNil());
21447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
21547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Attempt connect to listening socket.
21647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
21747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_FALSE(client->GetLocalAddress().IsNil());
21847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_NE(server->GetLocalAddress(), client->GetLocalAddress());
21947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
22047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Client is connecting, outcome not yet determined.
22147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
22247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN));
22347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
22447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
22547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Server has pending connection, accept it.
22647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
22747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
22847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT_TRUE(accepted);
22947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_FALSE(accept_addr.IsNil());
23047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
23147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
23247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Connected from server perspective, check the addresses are correct.
23347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
23447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
23547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
23647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
23747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Connected from client perspective, check the addresses are correct.
23847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
23947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
24047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
24147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
24247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
24347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
24447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
24547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::ConnectWithDnsLookupInternal(const IPAddress& loopback,
24647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                              const std::string& host) {
24747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  testing::StreamSink sink;
24847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress accept_addr;
24947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
25047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Create client.
25147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<AsyncSocket> client(
25247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
25347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sink.Monitor(client.get());
25447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
25547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Create server and listen.
25647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<AsyncSocket> server(
25747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
25847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sink.Monitor(server.get());
25947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
26047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, server->Listen(5));
26147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
26247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Attempt connect to listening socket.
26347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress dns_addr(server->GetLocalAddress());
26447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  dns_addr.SetIP(host);
26547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, client->Connect(dns_addr));
26647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // TODO: Bind when doing DNS lookup.
26747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  //EXPECT_NE(kEmptyAddr, client->GetLocalAddress());  // Implicit Bind
26847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
26947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Client is connecting, outcome not yet determined.
27047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
27147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN));
27247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
27347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
27447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Server has pending connection, accept it.
27547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
27647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
27747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT_TRUE(accepted);
27847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_FALSE(accept_addr.IsNil());
27947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(accepted->GetRemoteAddress(), accept_addr);
28047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
28147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Connected from server perspective, check the addresses are correct.
28247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
28347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
28447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
28547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
28647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Connected from client perspective, check the addresses are correct.
28747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
28847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
28947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
29047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
29147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
29247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
29347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
29447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::ConnectFailInternal(const IPAddress& loopback) {
29547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  testing::StreamSink sink;
29647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress accept_addr;
29747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
29847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Create client.
29947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<AsyncSocket> client(
30047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
30147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sink.Monitor(client.get());
30247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
30347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Create server, but don't listen yet.
30447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<AsyncSocket> server(
30547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
30647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sink.Monitor(server.get());
30747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
30847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
30947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Attempt connect to a non-existent socket.
31047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // We don't connect to the server socket created above, since on
31147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // MacOS it takes about 75 seconds to get back an error!
31247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress bogus_addr(loopback, 65535);
31347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, client->Connect(bogus_addr));
31447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
31547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Wait for connection to fail (ECONNREFUSED).
31647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
31747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN));
31847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_ERROR));
31947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(client->GetRemoteAddress().IsNil());
32047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
32147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Should be no pending server connections.
32247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ));
32347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(NULL == server->Accept(&accept_addr));
32447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(IPAddress(), accept_addr.ipaddr());
32547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
32647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
32747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::ConnectWithDnsLookupFailInternal(const IPAddress& loopback) {
32847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  testing::StreamSink sink;
32947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress accept_addr;
33047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
33147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Create client.
33247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<AsyncSocket> client(
33347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
33447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sink.Monitor(client.get());
33547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
33647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Create server, but don't listen yet.
33747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<AsyncSocket> server(
33847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
33947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sink.Monitor(server.get());
34047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
34147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
34247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Attempt connect to a non-existent host.
34347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // We don't connect to the server socket created above, since on
34447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // MacOS it takes about 75 seconds to get back an error!
34547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress bogus_dns_addr("not-a-real-hostname", 65535);
34647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, client->Connect(bogus_dns_addr));
34747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
34847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Wait for connection to fail (EHOSTNOTFOUND).
34947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool dns_lookup_finished = false;
35047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  WAIT_(client->GetState() == AsyncSocket::CS_CLOSED, kTimeout,
35147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        dns_lookup_finished);
35247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!dns_lookup_finished) {
35347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LOG(LS_WARNING) << "Skipping test; DNS resolution took longer than 5 "
35447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                    << "seconds.";
35547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return;
35647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
35747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
35847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
35947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_OPEN));
36047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_ERROR));
36147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(client->GetRemoteAddress().IsNil());
36247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Should be no pending server connections.
36347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ));
36447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(NULL == server->Accept(&accept_addr));
36547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(accept_addr.IsNil());
36647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
36747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
36847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::ConnectWithClosedSocketInternal(const IPAddress& loopback) {
36947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Create server and listen.
37047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<AsyncSocket> server(
37147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
37247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
37347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, server->Listen(5));
37447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
37547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Create a client and put in to CS_CLOSED state.
37647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<AsyncSocket> client(
37747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
37847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, client->Close());
37947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CLOSED, client->GetState());
38047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
38147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Connect() should reinitialize the socket, and put it in to CS_CONNECTING.
38247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
38347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
38447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
38547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
38647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::ConnectWhileNotClosedInternal(const IPAddress& loopback) {
38747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Create server and listen.
38847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  testing::StreamSink sink;
38947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<AsyncSocket> server(
39047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
39147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sink.Monitor(server.get());
39247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
39347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, server->Listen(5));
39447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Create client, connect.
39547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<AsyncSocket> client(
39647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
39747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, client->Connect(SocketAddress(server->GetLocalAddress())));
39847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CONNECTING, client->GetState());
39947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Try to connect again. Should fail, but not interfere with original attempt.
40047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(SOCKET_ERROR,
40147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org            client->Connect(SocketAddress(server->GetLocalAddress())));
40247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
40347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Accept the original connection.
40447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress accept_addr;
40547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
40647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
40747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT_TRUE(accepted);
40847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_FALSE(accept_addr.IsNil());
40947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
41047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Check the states and addresses.
41147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
41247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
41347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
41447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
41547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
41647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
41747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
41847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Try to connect again, to an unresolved hostname.
41947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Shouldn't break anything.
42047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(SOCKET_ERROR,
42147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org            client->Connect(SocketAddress("localhost",
42247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                          server->GetLocalAddress().port())));
42347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
42447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
42547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
42647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
42747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
42847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
42947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::ServerCloseDuringConnectInternal(const IPAddress& loopback) {
43047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  testing::StreamSink sink;
43147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
43247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Create client.
43347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<AsyncSocket> client(
43447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
43547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sink.Monitor(client.get());
43647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
43747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Create server and listen.
43847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<AsyncSocket> server(
43947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
44047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sink.Monitor(server.get());
44147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
44247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, server->Listen(5));
44347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
44447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Attempt connect to listening socket.
44547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
44647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
44747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Close down the server while the socket is in the accept queue.
44847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE_WAIT(sink.Check(server.get(), testing::SSE_READ), kTimeout);
44947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  server->Close();
45047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
45147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // This should fail the connection for the client. Clean up.
45247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
45347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_ERROR));
45447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  client->Close();
45547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
45647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
45747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::ClientCloseDuringConnectInternal(const IPAddress& loopback) {
45847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  testing::StreamSink sink;
45947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress accept_addr;
46047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
46147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Create client.
46247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<AsyncSocket> client(
46347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
46447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sink.Monitor(client.get());
46547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
46647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Create server and listen.
46747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<AsyncSocket> server(
46847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
46947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sink.Monitor(server.get());
47047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
47147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, server->Listen(5));
47247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
47347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Attempt connect to listening socket.
47447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
47547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
47647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Close down the client while the socket is in the accept queue.
47747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE_WAIT(sink.Check(server.get(), testing::SSE_READ), kTimeout);
47847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  client->Close();
47947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
48047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // The connection should still be able to be accepted.
48147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
48247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT_TRUE(accepted);
48347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sink.Monitor(accepted.get());
48447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
48547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
48647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // The accepted socket should then close (possibly with err, timing-related)
48747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, accepted->GetState(), kTimeout);
48847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(sink.Check(accepted.get(), testing::SSE_CLOSE) ||
48947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org              sink.Check(accepted.get(), testing::SSE_ERROR));
49047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
49147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // The client should not get a close event.
49247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
49347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
49447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
49547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::ServerCloseInternal(const IPAddress& loopback) {
49647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  testing::StreamSink sink;
49747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress accept_addr;
49847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
49947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Create client.
50047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<AsyncSocket> client(
50147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
50247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sink.Monitor(client.get());
50347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
50447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Create server and listen.
50547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<AsyncSocket> server(
50647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
50747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sink.Monitor(server.get());
50847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
50947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, server->Listen(5));
51047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
51147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Attempt connection.
51247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
51347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
51447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Accept connection.
51547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
51647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
51747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT_TRUE(accepted);
51847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sink.Monitor(accepted.get());
51947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
52047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Both sides are now connected.
52147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
52247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
52347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
52447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
52547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
52647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Send data to the client, and then close the connection.
52747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(1, accepted->Send("a", 1));
52847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  accepted->Close();
52947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CLOSED, accepted->GetState());
53047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
53147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Expect that the client is notified, and has not yet closed.
53247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE_WAIT(sink.Check(client.get(), testing::SSE_READ), kTimeout);
53347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
53447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
53547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
53647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Ensure the data can be read.
53747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  char buffer[10];
53847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(1, client->Recv(buffer, sizeof(buffer)));
53947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ('a', buffer[0]);
54047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
54147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Now we should close, but the remote address will remain.
54247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
54347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_CLOSE));
54447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_FALSE(client->GetRemoteAddress().IsAnyIP());
54547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
54647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // The closer should not get a close signal.
54747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_CLOSE));
54847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(accepted->GetRemoteAddress().IsNil());
54947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
55047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // And the closee should only get a single signal.
55147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Thread::Current()->ProcessMessages(0);
55247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
55347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
55447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Close down the client and ensure all is good.
55547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  client->Close();
55647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
55747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(client->GetRemoteAddress().IsNil());
55847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
55947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
56047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass SocketCloser : public sigslot::has_slots<> {
56147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org public:
56247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  void OnClose(AsyncSocket* socket, int error) {
56347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    socket->Close();  // Deleting here would blow up the vector of handlers
56447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                      // for the socket's signal.
56547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
56647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org};
56747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
56847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::CloseInClosedCallbackInternal(const IPAddress& loopback) {
56947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  testing::StreamSink sink;
57047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketCloser closer;
57147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress accept_addr;
57247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
57347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Create client.
57447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<AsyncSocket> client(
57547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
57647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sink.Monitor(client.get());
57747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  client->SignalCloseEvent.connect(&closer, &SocketCloser::OnClose);
57847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
57947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Create server and listen.
58047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<AsyncSocket> server(
58147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
58247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sink.Monitor(server.get());
58347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
58447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, server->Listen(5));
58547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
58647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Attempt connection.
58747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
58847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
58947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Accept connection.
59047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
59147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
59247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT_TRUE(accepted);
59347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sink.Monitor(accepted.get());
59447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
59547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Both sides are now connected.
59647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
59747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
59847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
59947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
60047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
60147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Send data to the client, and then close the connection.
60247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  accepted->Close();
60347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CLOSED, accepted->GetState());
60447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
60547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Expect that the client is notified, and has not yet closed.
60647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
60747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CONNECTED, client->GetState());
60847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
60947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Now we should be closed and invalidated
61047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
61147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_CLOSE));
61247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(Socket::CS_CLOSED == client->GetState());
61347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
61447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
61547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass Sleeper : public MessageHandler {
61647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org public:
61747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Sleeper() {}
61847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  void OnMessage(Message* msg) {
61947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    Thread::Current()->SleepMs(500);
62047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
62147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org};
62247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
62347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::SocketServerWaitInternal(const IPAddress& loopback) {
62447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  testing::StreamSink sink;
62547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress accept_addr;
62647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
62747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Create & connect server and client sockets.
62847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<AsyncSocket> client(
62947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
63047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<AsyncSocket> server(
63147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
63247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sink.Monitor(client.get());
63347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sink.Monitor(server.get());
63447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
63547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, server->Listen(5));
63647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
63747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
63847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
63947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
64047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
64147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT_TRUE(accepted);
64247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sink.Monitor(accepted.get());
64347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CONNECTED, accepted->GetState());
64447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(server->GetLocalAddress(), accepted->GetLocalAddress());
64547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(client->GetLocalAddress(), accepted->GetRemoteAddress());
64647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
64747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
64847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
64947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_FALSE(sink.Check(client.get(), testing::SSE_CLOSE));
65047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(client->GetRemoteAddress(), server->GetLocalAddress());
65147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
65247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
65347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Do an i/o operation, triggering an eventual callback.
65447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_READ));
65547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  char buf[1024] = {0};
65647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
65747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(1024, client->Send(buf, 1024));
65847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_READ));
65947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
66047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Shouldn't signal when blocked in a thread Send, where process_io is false.
66147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<Thread> thread(new Thread());
66247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  thread->Start();
66347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Sleeper sleeper;
66447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  TypedMessageData<AsyncSocket*> data(client.get());
66547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  thread->Send(&sleeper, 0, &data);
66647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_FALSE(sink.Check(accepted.get(), testing::SSE_READ));
66747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
66847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // But should signal when process_io is true.
66947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE_WAIT((sink.Check(accepted.get(), testing::SSE_READ)), kTimeout);
67047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_LT(0, accepted->Recv(buf, 1024));
67147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
67247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
67347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::TcpInternal(const IPAddress& loopback) {
67447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  testing::StreamSink sink;
67547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress accept_addr;
67647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
67747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Create test data.
67847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  const size_t kDataSize = 1024 * 1024;
67947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<char[]> send_buffer(new char[kDataSize]);
68047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<char[]> recv_buffer(new char[kDataSize]);
68147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t send_pos = 0, recv_pos = 0;
68247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  for (size_t i = 0; i < kDataSize; ++i) {
68347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    send_buffer[i] = static_cast<char>(i % 256);
68447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    recv_buffer[i] = 0;
68547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
68647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
68747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Create client.
68847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<AsyncSocket> client(
68947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
69047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sink.Monitor(client.get());
69147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
69247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Create server and listen.
69347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<AsyncSocket> server(
69447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
69547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sink.Monitor(server.get());
69647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
69747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, server->Listen(5));
69847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
69947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Attempt connection.
70047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
70147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
70247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Accept connection.
70347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
70447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
70547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT_TRUE(accepted);
70647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sink.Monitor(accepted.get());
70747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
70847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Both sides are now connected.
70947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
71047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
71147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
71247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
71347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
71447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Send and receive a bunch of data.
71547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool send_waiting_for_writability = false;
71647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool send_expect_success = true;
71747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool recv_waiting_for_readability = true;
71847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool recv_expect_success = false;
71947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int data_in_flight = 0;
72047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  while (recv_pos < kDataSize) {
72147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // Send as much as we can if we've been cleared to send.
72247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    while (!send_waiting_for_writability && send_pos < kDataSize) {
72347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      int tosend = static_cast<int>(kDataSize - send_pos);
72447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      int sent = accepted->Send(send_buffer.get() + send_pos, tosend);
72547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (send_expect_success) {
72647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        // The first Send() after connecting or getting writability should
72747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        // succeed and send some data.
72847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        EXPECT_GT(sent, 0);
72947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        send_expect_success = false;
73047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
73147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (sent >= 0) {
73247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        EXPECT_LE(sent, tosend);
73347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        send_pos += sent;
73447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        data_in_flight += sent;
73547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      } else {
73647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        ASSERT_TRUE(accepted->IsBlocking());
73747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        send_waiting_for_writability = true;
73847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
73947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
74047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
74147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // Read all the sent data.
74247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    while (data_in_flight > 0) {
74347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (recv_waiting_for_readability) {
74447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        // Wait until data is available.
74547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        EXPECT_TRUE_WAIT(sink.Check(client.get(), testing::SSE_READ), kTimeout);
74647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        recv_waiting_for_readability = false;
74747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        recv_expect_success = true;
74847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
74947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
75047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      // Receive as much as we can get in a single recv call.
75147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      int rcvd = client->Recv(recv_buffer.get() + recv_pos,
75247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                              kDataSize - recv_pos);
75347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
75447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (recv_expect_success) {
75547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        // The first Recv() after getting readability should succeed and receive
75647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        // some data.
75747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        // TODO: The following line is disabled due to flakey pulse
75847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        //     builds.  Re-enable if/when possible.
75947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        // EXPECT_GT(rcvd, 0);
76047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        recv_expect_success = false;
76147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
76247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (rcvd >= 0) {
76347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        EXPECT_LE(rcvd, data_in_flight);
76447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        recv_pos += rcvd;
76547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        data_in_flight -= rcvd;
76647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      } else {
76747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        ASSERT_TRUE(client->IsBlocking());
76847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        recv_waiting_for_readability = true;
76947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
77047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
77147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
77247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // Once all that we've sent has been rcvd, expect to be able to send again.
77347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (send_waiting_for_writability) {
77447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      EXPECT_TRUE_WAIT(sink.Check(accepted.get(), testing::SSE_WRITE),
77547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                       kTimeout);
77647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      send_waiting_for_writability = false;
77747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      send_expect_success = true;
77847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
77947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
78047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
78147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // The received data matches the sent data.
78247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(kDataSize, send_pos);
78347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(kDataSize, recv_pos);
78447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, memcmp(recv_buffer.get(), send_buffer.get(), kDataSize));
78547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
78647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Close down.
78747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  accepted->Close();
78847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ_WAIT(AsyncSocket::CS_CLOSED, client->GetState(), kTimeout);
78947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_CLOSE));
79047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  client->Close();
79147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
79247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
79347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::SingleFlowControlCallbackInternal(const IPAddress& loopback) {
79447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  testing::StreamSink sink;
79547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress accept_addr;
79647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
79747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Create client.
79847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<AsyncSocket> client(
79947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
80047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sink.Monitor(client.get());
80147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
80247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Create server and listen.
80347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<AsyncSocket> server(
80447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
80547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sink.Monitor(server.get());
80647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
80747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, server->Listen(5));
80847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
80947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Attempt connection.
81047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, client->Connect(server->GetLocalAddress()));
81147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
81247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Accept connection.
81347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
81447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
81547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT_TRUE(accepted);
81647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sink.Monitor(accepted.get());
81747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
81847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Both sides are now connected.
81947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ_WAIT(AsyncSocket::CS_CONNECTED, client->GetState(), kTimeout);
82047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(sink.Check(client.get(), testing::SSE_OPEN));
82147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(client->GetRemoteAddress(), accepted->GetLocalAddress());
82247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(accepted->GetRemoteAddress(), client->GetLocalAddress());
82347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
82447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Expect a writable callback from the connect.
82547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE_WAIT(sink.Check(accepted.get(), testing::SSE_WRITE), kTimeout);
82647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
82747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Fill the socket buffer.
82847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  char buf[1024 * 16] = {0};
82947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int sends = 0;
83047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  while (++sends && accepted->Send(&buf, ARRAY_SIZE(buf)) != -1) {}
83147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(accepted->IsBlocking());
83247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
83347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Wait until data is available.
83447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE_WAIT(sink.Check(client.get(), testing::SSE_READ), kTimeout);
83547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
83647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Pull data.
83747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  for (int i = 0; i < sends; ++i) {
83847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    client->Recv(buf, ARRAY_SIZE(buf));
83947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
84047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
84147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Expect at least one additional writable callback.
84247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE_WAIT(sink.Check(accepted.get(), testing::SSE_WRITE), kTimeout);
84347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
84447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Adding data in response to the writeable callback shouldn't cause infinite
84547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // callbacks.
84647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int extras = 0;
84747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  for (int i = 0; i < 100; ++i) {
84847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    accepted->Send(&buf, ARRAY_SIZE(buf));
84947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    rtc::Thread::Current()->ProcessMessages(1);
85047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (sink.Check(accepted.get(), testing::SSE_WRITE)) {
85147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      extras++;
85247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
85347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
85447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_LT(extras, 2);
85547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
85647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Close down.
85747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  accepted->Close();
85847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  client->Close();
85947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
86047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
86147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::UdpInternal(const IPAddress& loopback) {
86247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
86347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Test basic bind and connect behavior.
86447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  AsyncSocket* socket =
86547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM);
86647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CLOSED, socket->GetState());
86747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, socket->Bind(SocketAddress(loopback, 0)));
86847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress addr1 = socket->GetLocalAddress();
86947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(0, socket->Connect(addr1));
87047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CONNECTED, socket->GetState());
87147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  socket->Close();
87247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(AsyncSocket::CS_CLOSED, socket->GetState());
87347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  delete socket;
87447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
87547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Test send/receive behavior.
87647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<TestClient> client1(
87747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      new TestClient(AsyncUDPSocket::Create(ss_, addr1)));
87847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<TestClient> client2(
87947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      new TestClient(AsyncUDPSocket::Create(ss_, empty)));
88047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
88147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress addr2;
88247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
88347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr2));
88447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
88547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress addr3;
88647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr2));
88747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr3));
88847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(addr3, addr1);
88947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // TODO: figure out what the intent is here
89047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  for (int i = 0; i < 10; ++i) {
89147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    client2.reset(new TestClient(AsyncUDPSocket::Create(ss_, empty)));
89247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
89347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    SocketAddress addr4;
89447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    EXPECT_EQ(3, client2->SendTo("foo", 3, addr1));
89547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    EXPECT_TRUE(client1->CheckNextPacket("foo", 3, &addr4));
89647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    EXPECT_EQ(addr4.ipaddr(), addr2.ipaddr());
89747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
89847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    SocketAddress addr5;
89947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    EXPECT_EQ(6, client1->SendTo("bizbaz", 6, addr4));
90047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    EXPECT_TRUE(client2->CheckNextPacket("bizbaz", 6, &addr5));
90147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    EXPECT_EQ(addr5, addr1);
90247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
90347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    addr2 = addr4;
90447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
90547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
90647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
90747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::UdpReadyToSend(const IPAddress& loopback) {
90847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress empty = EmptySocketAddressWithFamily(loopback.family());
90947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // RFC 5737 - The blocks 192.0.2.0/24 (TEST-NET-1) ... are provided for use in
91047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // documentation.
91147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // RFC 3849 - 2001:DB8::/32 as a documentation-only prefix.
91247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  std::string dest = (loopback.family() == AF_INET6) ?
91347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      "2001:db8::1" : "192.0.2.0";
91447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress test_addr(dest, 2345);
91547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
91647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Test send
91747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<TestClient> client(
91847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      new TestClient(AsyncUDPSocket::Create(ss_, empty)));
91947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int test_packet_size = 1200;
92047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  rtc::scoped_ptr<char[]> test_packet(new char[test_packet_size]);
92147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Init the test packet just to avoid memcheck warning.
92247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  memset(test_packet.get(), 0, test_packet_size);
92347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Set the send buffer size to the same size as the test packet to have a
92447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // better chance to get EWOULDBLOCK.
92547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int send_buffer_size = test_packet_size;
92647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
92747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  send_buffer_size /= 2;
92847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif
92947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  client->SetOption(rtc::Socket::OPT_SNDBUF, send_buffer_size);
93047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
93147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int error = 0;
93247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  uint32 start_ms = Time();
93347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int sent_packet_num = 0;
93447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int expected_error = EWOULDBLOCK;
93547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  while (start_ms + kTimeout > Time()) {
93647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    int ret = client->SendTo(test_packet.get(), test_packet_size, test_addr);
93747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ++sent_packet_num;
93847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (ret != test_packet_size) {
93947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      error = client->GetError();
94047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (error == expected_error) {
94147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        LOG(LS_INFO) << "Got expected error code after sending "
94247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                     << sent_packet_num << " packets.";
94347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        break;
94447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
94547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
94647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
94747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_EQ(expected_error, error);
94847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_FALSE(client->ready_to_send());
94947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  EXPECT_TRUE_WAIT(client->ready_to_send(), kTimeout);
95047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  LOG(LS_INFO) << "Got SignalReadyToSend";
95147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
95247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
95347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid SocketTest::GetSetOptionsInternal(const IPAddress& loopback) {
95447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  rtc::scoped_ptr<AsyncSocket> socket(
95547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM));
95647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  socket->Bind(SocketAddress(loopback, 0));
95747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
95847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Check SNDBUF/RCVBUF.
95947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  const int desired_size = 12345;
96047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_LINUX)
96147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Yes, really.  It's in the kernel source.
96247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  const int expected_size = desired_size * 2;
96347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#else   // !WEBRTC_LINUX
96447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  const int expected_size = desired_size;
96547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif  // !WEBRTC_LINUX
96647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int recv_size = 0;
96747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int send_size = 0;
96847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // get the initial sizes
96947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
97047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
97147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // set our desired sizes
97247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT_NE(-1, socket->SetOption(Socket::OPT_RCVBUF, desired_size));
97347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT_NE(-1, socket->SetOption(Socket::OPT_SNDBUF, desired_size));
97447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // get the sizes again
97547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT_NE(-1, socket->GetOption(Socket::OPT_RCVBUF, &recv_size));
97647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT_NE(-1, socket->GetOption(Socket::OPT_SNDBUF, &send_size));
97747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // make sure they are right
97847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT_EQ(expected_size, recv_size);
97947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT_EQ(expected_size, send_size);
98047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
98147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Check that we can't set NODELAY on a UDP socket.
98247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int current_nd, desired_nd = 1;
98347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT_EQ(-1, socket->GetOption(Socket::OPT_NODELAY, &current_nd));
98447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT_EQ(-1, socket->SetOption(Socket::OPT_NODELAY, desired_nd));
98547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
98647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Skip the esimate MTU test for IPv6 for now.
98747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (loopback.family() != AF_INET6) {
98847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // Try estimating MTU.
98947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    rtc::scoped_ptr<AsyncSocket>
99047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        mtu_socket(
99147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org            ss_->CreateAsyncSocket(loopback.family(), SOCK_DGRAM));
99247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    mtu_socket->Bind(SocketAddress(loopback, 0));
99347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    uint16 mtu;
99447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // should fail until we connect
99547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ASSERT_EQ(-1, mtu_socket->EstimateMTU(&mtu));
99647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    mtu_socket->Connect(SocketAddress(loopback, 0));
99747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN)
99847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // now it should succeed
99947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ASSERT_NE(-1, mtu_socket->EstimateMTU(&mtu));
100047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ASSERT_GE(mtu, 1492);  // should be at least the 1492 "plateau" on localhost
100147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
100247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // except on WEBRTC_MAC && !WEBRTC_IOS, where it's not yet implemented
100347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ASSERT_EQ(-1, mtu_socket->EstimateMTU(&mtu));
100447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#else
100547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // and the behavior seems unpredictable on Linux,
100647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // failing on the build machine
100747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // but succeeding on my Ubiquity instance.
100847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif
100947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
101047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
101147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
101247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}  // namespace rtc
1013