147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org/*
247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  Copyright 2004 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/virtualsocketserver.h"
1247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <errno.h>
1447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <math.h>
1547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <algorithm>
1747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <map>
1847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <vector>
1947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
2047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/common.h"
2147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/logging.h"
2247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/physicalsocketserver.h"
2347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/socketaddresspair.h"
2447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/thread.h"
2547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/timeutils.h"
2647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
2747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgnamespace rtc {
2847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN)
2947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgconst in_addr kInitialNextIPv4 = { {0x01, 0, 0, 0} };
3047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#else
3147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// This value is entirely arbitrary, hence the lack of concern about endianness.
3247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgconst in_addr kInitialNextIPv4 = { 0x01000000 };
3347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif
3447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Starts at ::2 so as to not cause confusion with ::1.
3547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgconst in6_addr kInitialNextIPv6 = { { {
3647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2
3747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    } } };
3847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
3947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgconst uint16 kFirstEphemeralPort = 49152;
4047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgconst uint16 kLastEphemeralPort = 65535;
4147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgconst uint16 kEphemeralPortCount = kLastEphemeralPort - kFirstEphemeralPort + 1;
4247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgconst uint32 kDefaultNetworkCapacity = 64 * 1024;
4347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgconst uint32 kDefaultTcpBufferSize = 32 * 1024;
4447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
4547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgconst uint32 UDP_HEADER_SIZE = 28;  // IP + UDP headers
4647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgconst uint32 TCP_HEADER_SIZE = 40;  // IP + TCP headers
4747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgconst uint32 TCP_MSS = 1400;  // Maximum segment size
4847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
4947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Note: The current algorithm doesn't work for sample sizes smaller than this.
5047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgconst int NUM_SAMPLES = 1000;
5147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
5247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgenum {
5347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  MSG_ID_PACKET,
5447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  MSG_ID_CONNECT,
5547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  MSG_ID_DISCONNECT,
5647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org};
5747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
5847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Packets are passed between sockets as messages.  We copy the data just like
5947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// the kernel does.
6047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass Packet : public MessageData {
6147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org public:
6247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Packet(const char* data, size_t size, const SocketAddress& from)
6347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        : size_(size), consumed_(0), from_(from) {
6447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ASSERT(NULL != data);
6547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    data_ = new char[size_];
6647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    memcpy(data_, data, size_);
6747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
6847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
6947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual ~Packet() {
7047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    delete[] data_;
7147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
7247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
7347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  const char* data() const { return data_ + consumed_; }
7447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t size() const { return size_ - consumed_; }
7547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  const SocketAddress& from() const { return from_; }
7647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
7747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Remove the first size bytes from the data.
7847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  void Consume(size_t size) {
7947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ASSERT(size + consumed_ < size_);
8047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    consumed_ += size;
8147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
8247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
8347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org private:
8447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  char* data_;
8547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t size_, consumed_;
8647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress from_;
8747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org};
8847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
8947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstruct MessageAddress : public MessageData {
9047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  explicit MessageAddress(const SocketAddress& a) : addr(a) { }
9147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress addr;
9247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org};
9347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
9447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Implements the socket interface using the virtual network.  Packets are
9547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// passed as messages using the message queue of the socket server.
9647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass VirtualSocket : public AsyncSocket, public MessageHandler {
9747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org public:
9847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  VirtualSocket(VirtualSocketServer* server, int family, int type, bool async)
9947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      : server_(server), family_(family), type_(type), async_(async),
10047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        state_(CS_CLOSED), error_(0), listen_queue_(NULL),
10147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        write_enabled_(false),
10247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        network_size_(0), recv_buffer_size_(0), bound_(false), was_any_(false) {
10347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ASSERT((type_ == SOCK_DGRAM) || (type_ == SOCK_STREAM));
10447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ASSERT(async_ || (type_ != SOCK_STREAM));  // We only support async streams
10547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
10647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
10747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual ~VirtualSocket() {
10847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    Close();
10947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
11047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    for (RecvBuffer::iterator it = recv_buffer_.begin();
11147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org         it != recv_buffer_.end(); ++it) {
11247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      delete *it;
11347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
11447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
11547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
11647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual SocketAddress GetLocalAddress() const {
11747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return local_addr_;
11847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
11947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
12047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual SocketAddress GetRemoteAddress() const {
12147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return remote_addr_;
12247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
12347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
12447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Used by server sockets to set the local address without binding.
12547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  void SetLocalAddress(const SocketAddress& addr) {
12647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    local_addr_ = addr;
12747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
12847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
12947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual int Bind(const SocketAddress& addr) {
13047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (!local_addr_.IsNil()) {
13147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      error_ = EINVAL;
13247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      return -1;
13347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
13447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    local_addr_ = addr;
13547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    int result = server_->Bind(this, &local_addr_);
13647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (result != 0) {
13747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      local_addr_.Clear();
13847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      error_ = EADDRINUSE;
13947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    } else {
14047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      bound_ = true;
14147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      was_any_ = addr.IsAnyIP();
14247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
14347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return result;
14447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
14547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
14647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual int Connect(const SocketAddress& addr) {
14747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return InitiateConnect(addr, true);
14847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
14947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
15047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual int Close() {
15147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (!local_addr_.IsNil() && bound_) {
15247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      // Remove from the binding table.
15347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      server_->Unbind(local_addr_, this);
15447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      bound_ = false;
15547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
15647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
15747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (SOCK_STREAM == type_) {
15847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      // Cancel pending sockets
15947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (listen_queue_) {
16047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        while (!listen_queue_->empty()) {
16147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          SocketAddress addr = listen_queue_->front();
16247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
16347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          // Disconnect listening socket.
16447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          server_->Disconnect(server_->LookupBinding(addr));
16547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          listen_queue_->pop_front();
16647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        }
16747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        delete listen_queue_;
16847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        listen_queue_ = NULL;
16947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
17047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      // Disconnect stream sockets
17147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (CS_CONNECTED == state_) {
17247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        // Disconnect remote socket, check if it is a child of a server socket.
17347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        VirtualSocket* socket =
17447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org            server_->LookupConnection(local_addr_, remote_addr_);
17547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        if (!socket) {
17647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          // Not a server socket child, then see if it is bound.
17747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          // TODO: If this is indeed a server socket that has no
17847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          // children this will cause the server socket to be
17947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          // closed. This might lead to unexpected results, how to fix this?
18047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          socket = server_->LookupBinding(remote_addr_);
18147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        }
18247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        server_->Disconnect(socket);
18347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
18447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        // Remove mapping for both directions.
18547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        server_->RemoveConnection(remote_addr_, local_addr_);
18647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        server_->RemoveConnection(local_addr_, remote_addr_);
18747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
18847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      // Cancel potential connects
18947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      MessageList msgs;
19047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (server_->msg_queue_) {
19147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        server_->msg_queue_->Clear(this, MSG_ID_CONNECT, &msgs);
19247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
19347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      for (MessageList::iterator it = msgs.begin(); it != msgs.end(); ++it) {
19447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        ASSERT(NULL != it->pdata);
19547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        MessageAddress* data = static_cast<MessageAddress*>(it->pdata);
19647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
19747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        // Lookup remote side.
19847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        VirtualSocket* socket = server_->LookupConnection(local_addr_,
19947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                                          data->addr);
20047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        if (socket) {
20147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          // Server socket, remote side is a socket retreived by
20247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          // accept. Accepted sockets are not bound so we will not
20347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          // find it by looking in the bindings table.
20447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          server_->Disconnect(socket);
20547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          server_->RemoveConnection(local_addr_, data->addr);
20647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        } else {
20747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          server_->Disconnect(server_->LookupBinding(data->addr));
20847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        }
20947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        delete data;
21047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
21147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      // Clear incoming packets and disconnect messages
21247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (server_->msg_queue_) {
21347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        server_->msg_queue_->Clear(this);
21447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
21547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
21647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
21747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    state_ = CS_CLOSED;
21847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    local_addr_.Clear();
21947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    remote_addr_.Clear();
22047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return 0;
22147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
22247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
22347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual int Send(const void *pv, size_t cb) {
22447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (CS_CONNECTED != state_) {
22547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      error_ = ENOTCONN;
22647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      return -1;
22747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
22847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (SOCK_DGRAM == type_) {
22947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      return SendUdp(pv, cb, remote_addr_);
23047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    } else {
23147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      return SendTcp(pv, cb);
23247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
23347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
23447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
23547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual int SendTo(const void *pv, size_t cb, const SocketAddress& addr) {
23647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (SOCK_DGRAM == type_) {
23747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      return SendUdp(pv, cb, addr);
23847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    } else {
23947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (CS_CONNECTED != state_) {
24047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        error_ = ENOTCONN;
24147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        return -1;
24247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
24347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      return SendTcp(pv, cb);
24447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
24547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
24647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
24747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual int Recv(void *pv, size_t cb) {
24847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    SocketAddress addr;
24947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return RecvFrom(pv, cb, &addr);
25047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
25147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
25247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual int RecvFrom(void *pv, size_t cb, SocketAddress *paddr) {
25347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // If we don't have a packet, then either error or wait for one to arrive.
25447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (recv_buffer_.empty()) {
25547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (async_) {
25647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        error_ = EAGAIN;
25747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        return -1;
25847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
25947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      while (recv_buffer_.empty()) {
26047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        Message msg;
26147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        server_->msg_queue_->Get(&msg);
26247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        server_->msg_queue_->Dispatch(&msg);
26347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
26447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
26547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
26647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // Return the packet at the front of the queue.
26747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    Packet* packet = recv_buffer_.front();
26847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    size_t data_read = _min(cb, packet->size());
26947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    memcpy(pv, packet->data(), data_read);
27047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    *paddr = packet->from();
27147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
27247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (data_read < packet->size()) {
27347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      packet->Consume(data_read);
27447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    } else {
27547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      recv_buffer_.pop_front();
27647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      delete packet;
27747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
27847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
27947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (SOCK_STREAM == type_) {
28047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      bool was_full = (recv_buffer_size_ == server_->recv_buffer_capacity_);
28147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      recv_buffer_size_ -= data_read;
28247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (was_full) {
28347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        VirtualSocket* sender = server_->LookupBinding(remote_addr_);
28447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        ASSERT(NULL != sender);
28547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        server_->SendTcp(sender);
28647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
28747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
28847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
28947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return static_cast<int>(data_read);
29047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
29147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
29247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual int Listen(int backlog) {
29347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ASSERT(SOCK_STREAM == type_);
29447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ASSERT(CS_CLOSED == state_);
29547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (local_addr_.IsNil()) {
29647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      error_ = EINVAL;
29747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      return -1;
29847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
29947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ASSERT(NULL == listen_queue_);
30047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    listen_queue_ = new ListenQueue;
30147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    state_ = CS_CONNECTING;
30247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return 0;
30347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
30447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
30547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual VirtualSocket* Accept(SocketAddress *paddr) {
30647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (NULL == listen_queue_) {
30747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      error_ = EINVAL;
30847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      return NULL;
30947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
31047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    while (!listen_queue_->empty()) {
31147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      VirtualSocket* socket = new VirtualSocket(server_, AF_INET, type_,
31247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                                async_);
31347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
31447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      // Set the new local address to the same as this server socket.
31547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      socket->SetLocalAddress(local_addr_);
31647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      // Sockets made from a socket that 'was Any' need to inherit that.
31747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      socket->set_was_any(was_any_);
31847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      SocketAddress remote_addr(listen_queue_->front());
31947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      int result = socket->InitiateConnect(remote_addr, false);
32047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      listen_queue_->pop_front();
32147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (result != 0) {
32247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        delete socket;
32347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        continue;
32447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
32547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      socket->CompleteConnect(remote_addr, false);
32647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (paddr) {
32747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        *paddr = remote_addr;
32847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
32947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      return socket;
33047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
33147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    error_ = EWOULDBLOCK;
33247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return NULL;
33347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
33447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
33547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual int GetError() const {
33647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return error_;
33747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
33847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
33947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual void SetError(int error) {
34047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    error_ = error;
34147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
34247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
34347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual ConnState GetState() const {
34447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return state_;
34547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
34647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
34747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual int GetOption(Option opt, int* value) {
34847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    OptionsMap::const_iterator it = options_map_.find(opt);
34947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (it == options_map_.end()) {
35047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      return -1;
35147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
35247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    *value = it->second;
35347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return 0;  // 0 is success to emulate getsockopt()
35447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
35547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
35647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual int SetOption(Option opt, int value) {
35747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    options_map_[opt] = value;
35847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return 0;  // 0 is success to emulate setsockopt()
35947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
36047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
36147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual int EstimateMTU(uint16* mtu) {
36247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (CS_CONNECTED != state_)
36347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      return ENOTCONN;
36447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    else
36547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      return 65536;
36647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
36747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
36847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  void OnMessage(Message *pmsg) {
36947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (pmsg->message_id == MSG_ID_PACKET) {
37047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      //ASSERT(!local_addr_.IsAny());
37147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ASSERT(NULL != pmsg->pdata);
37247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      Packet* packet = static_cast<Packet*>(pmsg->pdata);
37347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
37447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      recv_buffer_.push_back(packet);
37547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
37647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (async_) {
37747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        SignalReadEvent(this);
37847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
37947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    } else if (pmsg->message_id == MSG_ID_CONNECT) {
38047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ASSERT(NULL != pmsg->pdata);
38147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      MessageAddress* data = static_cast<MessageAddress*>(pmsg->pdata);
38247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (listen_queue_ != NULL) {
38347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        listen_queue_->push_back(data->addr);
38447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        if (async_) {
38547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          SignalReadEvent(this);
38647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        }
38747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      } else if ((SOCK_STREAM == type_) && (CS_CONNECTING == state_)) {
38847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        CompleteConnect(data->addr, true);
38947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      } else {
39047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        LOG(LS_VERBOSE) << "Socket at " << local_addr_ << " is not listening";
39147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        server_->Disconnect(server_->LookupBinding(data->addr));
39247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
39347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      delete data;
39447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    } else if (pmsg->message_id == MSG_ID_DISCONNECT) {
39547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ASSERT(SOCK_STREAM == type_);
39647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (CS_CLOSED != state_) {
39747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        int error = (CS_CONNECTING == state_) ? ECONNREFUSED : 0;
39847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        state_ = CS_CLOSED;
39947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        remote_addr_.Clear();
40047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        if (async_) {
40147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          SignalCloseEvent(this, error);
40247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        }
40347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
40447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    } else {
40547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ASSERT(false);
40647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
40747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
40847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
40947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool was_any() { return was_any_; }
41047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  void set_was_any(bool was_any) { was_any_ = was_any; }
41147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
41247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org private:
41347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  struct NetworkEntry {
41447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    size_t size;
41547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    uint32 done_time;
41647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  };
41747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
41847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  typedef std::deque<SocketAddress> ListenQueue;
41947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  typedef std::deque<NetworkEntry> NetworkQueue;
42047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  typedef std::vector<char> SendBuffer;
42147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  typedef std::list<Packet*> RecvBuffer;
42247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  typedef std::map<Option, int> OptionsMap;
42347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
42447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int InitiateConnect(const SocketAddress& addr, bool use_delay) {
42547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (!remote_addr_.IsNil()) {
42647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      error_ = (CS_CONNECTED == state_) ? EISCONN : EINPROGRESS;
42747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      return -1;
42847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
42947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (local_addr_.IsNil()) {
43047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      // If there's no local address set, grab a random one in the correct AF.
43147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      int result = 0;
43247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (addr.ipaddr().family() == AF_INET) {
43347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        result = Bind(SocketAddress("0.0.0.0", 0));
43447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      } else if (addr.ipaddr().family() == AF_INET6) {
43547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        result = Bind(SocketAddress("::", 0));
43647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
43747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (result != 0) {
43847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        return result;
43947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
44047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
44147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (type_ == SOCK_DGRAM) {
44247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      remote_addr_ = addr;
44347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      state_ = CS_CONNECTED;
44447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    } else {
44547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      int result = server_->Connect(this, addr, use_delay);
44647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (result != 0) {
44747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        error_ = EHOSTUNREACH;
44847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        return -1;
44947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
45047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      state_ = CS_CONNECTING;
45147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
45247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return 0;
45347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
45447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
45547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  void CompleteConnect(const SocketAddress& addr, bool notify) {
45647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ASSERT(CS_CONNECTING == state_);
45747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    remote_addr_ = addr;
45847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    state_ = CS_CONNECTED;
45947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    server_->AddConnection(remote_addr_, local_addr_, this);
46047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (async_ && notify) {
46147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      SignalConnectEvent(this);
46247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
46347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
46447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
46547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int SendUdp(const void* pv, size_t cb, const SocketAddress& addr) {
46647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // If we have not been assigned a local port, then get one.
46747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (local_addr_.IsNil()) {
46847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      local_addr_ = EmptySocketAddressWithFamily(addr.ipaddr().family());
46947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      int result = server_->Bind(this, &local_addr_);
47047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (result != 0) {
47147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        local_addr_.Clear();
47247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        error_ = EADDRINUSE;
47347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        return result;
47447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
47547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
47647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
47747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // Send the data in a message to the appropriate socket.
47847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return server_->SendUdp(this, static_cast<const char*>(pv), cb, addr);
47947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
48047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
48147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int SendTcp(const void* pv, size_t cb) {
48247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    size_t capacity = server_->send_buffer_capacity_ - send_buffer_.size();
48347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (0 == capacity) {
48447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      write_enabled_ = true;
48547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      error_ = EWOULDBLOCK;
48647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      return -1;
48747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
48847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    size_t consumed = _min(cb, capacity);
48947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    const char* cpv = static_cast<const char*>(pv);
49047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    send_buffer_.insert(send_buffer_.end(), cpv, cpv + consumed);
49147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    server_->SendTcp(this);
49247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return static_cast<int>(consumed);
49347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
49447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
49547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  VirtualSocketServer* server_;
49647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int family_;
49747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int type_;
49847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool async_;
49947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ConnState state_;
50047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int error_;
50147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress local_addr_;
50247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress remote_addr_;
50347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
50447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Pending sockets which can be Accepted
50547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ListenQueue* listen_queue_;
50647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
50747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Data which tcp has buffered for sending
50847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SendBuffer send_buffer_;
50947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool write_enabled_;
51047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
51147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Critical section to protect the recv_buffer and queue_
51247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CriticalSection crit_;
51347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
51447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Network model that enforces bandwidth and capacity constraints
51547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  NetworkQueue network_;
51647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t network_size_;
51747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
51847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Data which has been received from the network
51947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  RecvBuffer recv_buffer_;
52047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // The amount of data which is in flight or in recv_buffer_
52147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t recv_buffer_size_;
52247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
52347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Is this socket bound?
52447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool bound_;
52547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
52647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // When we bind a socket to Any, VSS's Bind gives it another address. For
52747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // dual-stack sockets, we want to distinguish between sockets that were
52847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // explicitly given a particular address and sockets that had one picked
52947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // for them by VSS.
53047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool was_any_;
53147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
53247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Store the options that are set
53347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  OptionsMap options_map_;
53447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
53547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  friend class VirtualSocketServer;
53647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org};
53747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
53847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgVirtualSocketServer::VirtualSocketServer(SocketServer* ss)
53947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    : server_(ss), server_owned_(false), msg_queue_(NULL), stop_on_idle_(false),
54047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      network_delay_(Time()), next_ipv4_(kInitialNextIPv4),
54147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      next_ipv6_(kInitialNextIPv6), next_port_(kFirstEphemeralPort),
54247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      bindings_(new AddressMap()), connections_(new ConnectionMap()),
54347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      bandwidth_(0), network_capacity_(kDefaultNetworkCapacity),
54447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      send_buffer_capacity_(kDefaultTcpBufferSize),
54547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      recv_buffer_capacity_(kDefaultTcpBufferSize),
54647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      delay_mean_(0), delay_stddev_(0), delay_samples_(NUM_SAMPLES),
54747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      delay_dist_(NULL), drop_prob_(0.0) {
54847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!server_) {
54947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    server_ = new PhysicalSocketServer();
55047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    server_owned_ = true;
55147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
55247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  UpdateDelayDistribution();
55347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
55447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
55547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgVirtualSocketServer::~VirtualSocketServer() {
55647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  delete bindings_;
55747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  delete connections_;
55847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  delete delay_dist_;
55947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (server_owned_) {
56047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    delete server_;
56147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
56247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
56347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
56447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgIPAddress VirtualSocketServer::GetNextIP(int family) {
56547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (family == AF_INET) {
56647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    IPAddress next_ip(next_ipv4_);
56747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    next_ipv4_.s_addr =
56847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        HostToNetwork32(NetworkToHost32(next_ipv4_.s_addr) + 1);
56947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return next_ip;
57047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } else if (family == AF_INET6) {
57147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    IPAddress next_ip(next_ipv6_);
57247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    uint32* as_ints = reinterpret_cast<uint32*>(&next_ipv6_.s6_addr);
57347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    as_ints[3] += 1;
57447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return next_ip;
57547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
57647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return IPAddress();
57747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
57847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
57947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orguint16 VirtualSocketServer::GetNextPort() {
58047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  uint16 port = next_port_;
58147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (next_port_ < kLastEphemeralPort) {
58247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ++next_port_;
58347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } else {
58447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    next_port_ = kFirstEphemeralPort;
58547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
58647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return port;
58747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
58847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
58947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgSocket* VirtualSocketServer::CreateSocket(int type) {
59047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return CreateSocket(AF_INET, type);
59147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
59247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
59347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgSocket* VirtualSocketServer::CreateSocket(int family, int type) {
59447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return CreateSocketInternal(family, type);
59547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
59647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
59747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgAsyncSocket* VirtualSocketServer::CreateAsyncSocket(int type) {
59847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return CreateAsyncSocket(AF_INET, type);
59947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
60047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
60147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgAsyncSocket* VirtualSocketServer::CreateAsyncSocket(int family, int type) {
60247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return CreateSocketInternal(family, type);
60347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
60447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
60547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgVirtualSocket* VirtualSocketServer::CreateSocketInternal(int family, int type) {
60647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return new VirtualSocket(this, family, type, true);
60747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
60847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
60947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid VirtualSocketServer::SetMessageQueue(MessageQueue* msg_queue) {
61047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  msg_queue_ = msg_queue;
61147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (msg_queue_) {
61247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    msg_queue_->SignalQueueDestroyed.connect(this,
61347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        &VirtualSocketServer::OnMessageQueueDestroyed);
61447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
61547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
61647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
61747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool VirtualSocketServer::Wait(int cmsWait, bool process_io) {
61847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(msg_queue_ == Thread::Current());
61947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (stop_on_idle_ && Thread::Current()->empty()) {
62047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
62147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
62247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return socketserver()->Wait(cmsWait, process_io);
62347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
62447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
62547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid VirtualSocketServer::WakeUp() {
62647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  socketserver()->WakeUp();
62747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
62847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
62947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool VirtualSocketServer::ProcessMessagesUntilIdle() {
63047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(msg_queue_ == Thread::Current());
63147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  stop_on_idle_ = true;
63247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  while (!msg_queue_->empty()) {
63347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    Message msg;
63447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (msg_queue_->Get(&msg, kForever)) {
63547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      msg_queue_->Dispatch(&msg);
63647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
63747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
63847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  stop_on_idle_ = false;
63947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return !msg_queue_->IsQuitting();
64047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
64147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
6420cdce7c07a77d724f5d7f5f85918b1a1fb9a7e62jiayl@webrtc.orgvoid VirtualSocketServer::SetNextPortForTesting(uint16 port) {
6430cdce7c07a77d724f5d7f5f85918b1a1fb9a7e62jiayl@webrtc.org  next_port_ = port;
6440cdce7c07a77d724f5d7f5f85918b1a1fb9a7e62jiayl@webrtc.org}
6450cdce7c07a77d724f5d7f5f85918b1a1fb9a7e62jiayl@webrtc.org
64647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgint VirtualSocketServer::Bind(VirtualSocket* socket,
64747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                              const SocketAddress& addr) {
64847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(NULL != socket);
64947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Address must be completely specified at this point
65047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(!IPIsUnspec(addr.ipaddr()));
65147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(addr.port() != 0);
65247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
65347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Normalize the address (turns v6-mapped addresses into v4-addresses).
65447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress normalized(addr.ipaddr().Normalized(), addr.port());
65547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
65647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  AddressMap::value_type entry(normalized, socket);
65747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return bindings_->insert(entry).second ? 0 : -1;
65847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
65947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
66047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgint VirtualSocketServer::Bind(VirtualSocket* socket, SocketAddress* addr) {
66147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(NULL != socket);
66247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
66347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (IPIsAny(addr->ipaddr())) {
66447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    addr->SetIP(GetNextIP(addr->ipaddr().family()));
66547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } else if (!IPIsUnspec(addr->ipaddr())) {
66647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    addr->SetIP(addr->ipaddr().Normalized());
66747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } else {
66847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ASSERT(false);
66947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
67047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
67147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (addr->port() == 0) {
67247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    for (int i = 0; i < kEphemeralPortCount; ++i) {
67347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      addr->SetPort(GetNextPort());
67447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (bindings_->find(*addr) == bindings_->end()) {
67547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        break;
67647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
67747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
67847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
67947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
68047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return Bind(socket, *addr);
68147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
68247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
68347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgVirtualSocket* VirtualSocketServer::LookupBinding(const SocketAddress& addr) {
68447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress normalized(addr.ipaddr().Normalized(),
68547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                           addr.port());
68647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  AddressMap::iterator it = bindings_->find(normalized);
68747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return (bindings_->end() != it) ? it->second : NULL;
68847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
68947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
69047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgint VirtualSocketServer::Unbind(const SocketAddress& addr,
69147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                VirtualSocket* socket) {
69247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress normalized(addr.ipaddr().Normalized(),
69347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                           addr.port());
69447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT((*bindings_)[normalized] == socket);
69547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bindings_->erase(bindings_->find(normalized));
69647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return 0;
69747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
69847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
69947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid VirtualSocketServer::AddConnection(const SocketAddress& local,
70047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                        const SocketAddress& remote,
70147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                        VirtualSocket* remote_socket) {
70247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Add this socket pair to our routing table. This will allow
70347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // multiple clients to connect to the same server address.
70447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress local_normalized(local.ipaddr().Normalized(),
70547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                 local.port());
70647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress remote_normalized(remote.ipaddr().Normalized(),
70747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                  remote.port());
70847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddressPair address_pair(local_normalized, remote_normalized);
70947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  connections_->insert(std::pair<SocketAddressPair,
71047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                       VirtualSocket*>(address_pair, remote_socket));
71147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
71247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
71347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgVirtualSocket* VirtualSocketServer::LookupConnection(
71447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    const SocketAddress& local,
71547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    const SocketAddress& remote) {
71647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress local_normalized(local.ipaddr().Normalized(),
71747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                 local.port());
71847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress remote_normalized(remote.ipaddr().Normalized(),
71947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                  remote.port());
72047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddressPair address_pair(local_normalized, remote_normalized);
72147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ConnectionMap::iterator it = connections_->find(address_pair);
72247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return (connections_->end() != it) ? it->second : NULL;
72347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
72447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
72547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid VirtualSocketServer::RemoveConnection(const SocketAddress& local,
72647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                           const SocketAddress& remote) {
72747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress local_normalized(local.ipaddr().Normalized(),
72847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                local.port());
72947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddress remote_normalized(remote.ipaddr().Normalized(),
73047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                 remote.port());
73147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SocketAddressPair address_pair(local_normalized, remote_normalized);
73247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  connections_->erase(address_pair);
73347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
73447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
73547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic double Random() {
73647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return static_cast<double>(rand()) / RAND_MAX;
73747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
73847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
73947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgint VirtualSocketServer::Connect(VirtualSocket* socket,
74047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                 const SocketAddress& remote_addr,
74147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                 bool use_delay) {
74247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  uint32 delay = use_delay ? GetRandomTransitDelay() : 0;
74347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  VirtualSocket* remote = LookupBinding(remote_addr);
74447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!CanInteractWith(socket, remote)) {
74547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LOG(LS_INFO) << "Address family mismatch between "
74647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                 << socket->GetLocalAddress() << " and " << remote_addr;
74747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return -1;
74847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
74947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (remote != NULL) {
75047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    SocketAddress addr = socket->GetLocalAddress();
75147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    msg_queue_->PostDelayed(delay, remote, MSG_ID_CONNECT,
75247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                            new MessageAddress(addr));
75347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } else {
75447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LOG(LS_INFO) << "No one listening at " << remote_addr;
75547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    msg_queue_->PostDelayed(delay, socket, MSG_ID_DISCONNECT);
75647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
75747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return 0;
75847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
75947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
76047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool VirtualSocketServer::Disconnect(VirtualSocket* socket) {
76147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (socket) {
76247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // Remove the mapping.
76347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    msg_queue_->Post(socket, MSG_ID_DISCONNECT);
76447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return true;
76547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
76647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return false;
76747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
76847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
76947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgint VirtualSocketServer::SendUdp(VirtualSocket* socket,
77047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                 const char* data, size_t data_size,
77147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                 const SocketAddress& remote_addr) {
77247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // See if we want to drop this packet.
77347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (Random() < drop_prob_) {
77447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LOG(LS_VERBOSE) << "Dropping packet: bad luck";
77547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return static_cast<int>(data_size);
77647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
77747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
77847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  VirtualSocket* recipient = LookupBinding(remote_addr);
77947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!recipient) {
78047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // Make a fake recipient for address family checking.
78147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    scoped_ptr<VirtualSocket> dummy_socket(
78247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        CreateSocketInternal(AF_INET, SOCK_DGRAM));
78347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    dummy_socket->SetLocalAddress(remote_addr);
78447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (!CanInteractWith(socket, dummy_socket.get())) {
78547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      LOG(LS_VERBOSE) << "Incompatible address families: "
78647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                      << socket->GetLocalAddress() << " and " << remote_addr;
78747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      return -1;
78847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
78947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LOG(LS_VERBOSE) << "No one listening at " << remote_addr;
79047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return static_cast<int>(data_size);
79147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
79247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
79347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!CanInteractWith(socket, recipient)) {
79447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LOG(LS_VERBOSE) << "Incompatible address families: "
79547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                    << socket->GetLocalAddress() << " and " << remote_addr;
79647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return -1;
79747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
79847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
79947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CritScope cs(&socket->crit_);
80047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
80147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  uint32 cur_time = Time();
80247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  PurgeNetworkPackets(socket, cur_time);
80347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
80447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Determine whether we have enough bandwidth to accept this packet.  To do
80547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // this, we need to update the send queue.  Once we know it's current size,
80647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // we know whether we can fit this packet.
80747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  //
80847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // NOTE: There are better algorithms for maintaining such a queue (such as
80947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // "Derivative Random Drop"); however, this algorithm is a more accurate
81047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // simulation of what a normal network would do.
81147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
81247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t packet_size = data_size + UDP_HEADER_SIZE;
81347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (socket->network_size_ + packet_size > network_capacity_) {
81447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LOG(LS_VERBOSE) << "Dropping packet: network capacity exceeded";
81547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return static_cast<int>(data_size);
81647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
81747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
81847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  AddPacketToNetwork(socket, recipient, cur_time, data, data_size,
81947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                     UDP_HEADER_SIZE, false);
82047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
82147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return static_cast<int>(data_size);
82247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
82347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
82447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid VirtualSocketServer::SendTcp(VirtualSocket* socket) {
82547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // TCP can't send more data than will fill up the receiver's buffer.
82647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // We track the data that is in the buffer plus data in flight using the
82747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // recipient's recv_buffer_size_.  Anything beyond that must be stored in the
82847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // sender's buffer.  We will trigger the buffered data to be sent when data
82947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // is read from the recv_buffer.
83047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
83147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Lookup the local/remote pair in the connections table.
83247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  VirtualSocket* recipient = LookupConnection(socket->local_addr_,
83347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                              socket->remote_addr_);
83447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!recipient) {
83547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LOG(LS_VERBOSE) << "Sending data to no one.";
83647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return;
83747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
83847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
83947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CritScope cs(&socket->crit_);
84047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
84147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  uint32 cur_time = Time();
84247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  PurgeNetworkPackets(socket, cur_time);
84347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
84447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  while (true) {
84547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    size_t available = recv_buffer_capacity_ - recipient->recv_buffer_size_;
84647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    size_t max_data_size = _min<size_t>(available, TCP_MSS - TCP_HEADER_SIZE);
84747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    size_t data_size = _min(socket->send_buffer_.size(), max_data_size);
84847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (0 == data_size)
84947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      break;
85047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
85147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    AddPacketToNetwork(socket, recipient, cur_time, &socket->send_buffer_[0],
85247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                       data_size, TCP_HEADER_SIZE, true);
85347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    recipient->recv_buffer_size_ += data_size;
85447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
85547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    size_t new_buffer_size = socket->send_buffer_.size() - data_size;
85647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // Avoid undefined access beyond the last element of the vector.
85747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // This only happens when new_buffer_size is 0.
85847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (data_size < socket->send_buffer_.size()) {
85947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      // memmove is required for potentially overlapping source/destination.
86047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      memmove(&socket->send_buffer_[0], &socket->send_buffer_[data_size],
86147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org              new_buffer_size);
86247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
86347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    socket->send_buffer_.resize(new_buffer_size);
86447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
86547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
86647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (socket->write_enabled_
86747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      && (socket->send_buffer_.size() < send_buffer_capacity_)) {
86847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    socket->write_enabled_ = false;
86947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    socket->SignalWriteEvent(socket);
87047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
87147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
87247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
87347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid VirtualSocketServer::AddPacketToNetwork(VirtualSocket* sender,
87447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                             VirtualSocket* recipient,
87547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                             uint32 cur_time,
87647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                             const char* data,
87747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                             size_t data_size,
87847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                             size_t header_size,
87947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                             bool ordered) {
88047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  VirtualSocket::NetworkEntry entry;
88147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  entry.size = data_size + header_size;
88247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
88347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sender->network_size_ += entry.size;
88447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  uint32 send_delay = SendDelay(static_cast<uint32>(sender->network_size_));
88547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  entry.done_time = cur_time + send_delay;
88647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  sender->network_.push_back(entry);
88747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
88847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Find the delay for crossing the many virtual hops of the network.
88947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  uint32 transit_delay = GetRandomTransitDelay();
89047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
89147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Post the packet as a message to be delivered (on our own thread)
89247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Packet* p = new Packet(data, data_size, sender->local_addr_);
89347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  uint32 ts = TimeAfter(send_delay + transit_delay);
89447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (ordered) {
89547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // Ensure that new packets arrive after previous ones
89647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // TODO: consider ordering on a per-socket basis, since this
89747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // introduces artifical delay.
89847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ts = TimeMax(ts, network_delay_);
89947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
90047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  msg_queue_->PostAt(ts, recipient, MSG_ID_PACKET, p);
90147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  network_delay_ = TimeMax(ts, network_delay_);
90247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
90347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
90447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid VirtualSocketServer::PurgeNetworkPackets(VirtualSocket* socket,
90547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                              uint32 cur_time) {
90647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  while (!socket->network_.empty() &&
90747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org         (socket->network_.front().done_time <= cur_time)) {
90847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ASSERT(socket->network_size_ >= socket->network_.front().size);
90947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    socket->network_size_ -= socket->network_.front().size;
91047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    socket->network_.pop_front();
91147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
91247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
91347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
91447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orguint32 VirtualSocketServer::SendDelay(uint32 size) {
91547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (bandwidth_ == 0)
91647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return 0;
91747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  else
91847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return 1000 * size / bandwidth_;
91947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
92047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
92147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if 0
92247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid PrintFunction(std::vector<std::pair<double, double> >* f) {
92347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return;
92447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  double sum = 0;
92547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  for (uint32 i = 0; i < f->size(); ++i) {
92647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    std::cout << (*f)[i].first << '\t' << (*f)[i].second << std::endl;
92747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    sum += (*f)[i].second;
92847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
92947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!f->empty()) {
93047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    const double mean = sum / f->size();
93147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    double sum_sq_dev = 0;
93247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    for (uint32 i = 0; i < f->size(); ++i) {
93347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      double dev = (*f)[i].second - mean;
93447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      sum_sq_dev += dev * dev;
93547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
93647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    std::cout << "Mean = " << mean << " StdDev = "
93747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org              << sqrt(sum_sq_dev / f->size()) << std::endl;
93847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
93947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
94047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif  // <unused>
94147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
94247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid VirtualSocketServer::UpdateDelayDistribution() {
94347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Function* dist = CreateDistribution(delay_mean_, delay_stddev_,
94447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                      delay_samples_);
94547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // We take a lock just to make sure we don't leak memory.
94647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  {
94747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    CritScope cs(&delay_crit_);
94847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    delete delay_dist_;
94947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    delay_dist_ = dist;
95047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
95147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
95247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
95347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic double PI = 4 * atan(1.0);
95447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
95547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic double Normal(double x, double mean, double stddev) {
95647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  double a = (x - mean) * (x - mean) / (2 * stddev * stddev);
95747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return exp(-a) / (stddev * sqrt(2 * PI));
95847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
95947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
96047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if 0  // static unused gives a warning
96147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic double Pareto(double x, double min, double k) {
96247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (x < min)
96347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return 0;
96447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  else
96547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return k * std::pow(min, k) / std::pow(x, k+1);
96647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
96747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif
96847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
96947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgVirtualSocketServer::Function* VirtualSocketServer::CreateDistribution(
97047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    uint32 mean, uint32 stddev, uint32 samples) {
97147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Function* f = new Function();
97247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
97347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (0 == stddev) {
97447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    f->push_back(Point(mean, 1.0));
97547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } else {
97647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    double start = 0;
97747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (mean >= 4 * static_cast<double>(stddev))
97847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      start = mean - 4 * static_cast<double>(stddev);
97947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    double end = mean + 4 * static_cast<double>(stddev);
98047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
98147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    for (uint32 i = 0; i < samples; i++) {
98247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      double x = start + (end - start) * i / (samples - 1);
98347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      double y = Normal(x, mean, stddev);
98447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      f->push_back(Point(x, y));
98547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
98647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
98747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return Resample(Invert(Accumulate(f)), 0, 1, samples);
98847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
98947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
99047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orguint32 VirtualSocketServer::GetRandomTransitDelay() {
99147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  size_t index = rand() % delay_dist_->size();
99247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  double delay = (*delay_dist_)[index].second;
99347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  //LOG_F(LS_INFO) << "random[" << index << "] = " << delay;
99447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return static_cast<uint32>(delay);
99547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
99647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
99747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstruct FunctionDomainCmp {
99847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool operator()(const VirtualSocketServer::Point& p1,
99947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                   const VirtualSocketServer::Point& p2) {
100047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return p1.first < p2.first;
100147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
100247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool operator()(double v1, const VirtualSocketServer::Point& p2) {
100347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return v1 < p2.first;
100447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
100547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool operator()(const VirtualSocketServer::Point& p1, double v2) {
100647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return p1.first < v2;
100747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
100847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org};
100947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
101047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgVirtualSocketServer::Function* VirtualSocketServer::Accumulate(Function* f) {
101147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(f->size() >= 1);
101247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  double v = 0;
101347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  for (Function::size_type i = 0; i < f->size() - 1; ++i) {
101447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    double dx = (*f)[i + 1].first - (*f)[i].first;
101547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    double avgy = ((*f)[i + 1].second + (*f)[i].second) / 2;
101647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    (*f)[i].second = v;
101747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    v = v + dx * avgy;
101847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
101947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  (*f)[f->size()-1].second = v;
102047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return f;
102147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
102247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
102347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgVirtualSocketServer::Function* VirtualSocketServer::Invert(Function* f) {
102447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  for (Function::size_type i = 0; i < f->size(); ++i)
102547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    std::swap((*f)[i].first, (*f)[i].second);
102647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
102747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  std::sort(f->begin(), f->end(), FunctionDomainCmp());
102847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return f;
102947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
103047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
103147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgVirtualSocketServer::Function* VirtualSocketServer::Resample(
103247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    Function* f, double x1, double x2, uint32 samples) {
103347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Function* g = new Function();
103447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
103547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  for (size_t i = 0; i < samples; i++) {
103647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    double x = x1 + (x2 - x1) * i / (samples - 1);
103747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    double y = Evaluate(f, x);
103847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    g->push_back(Point(x, y));
103947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
104047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
104147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  delete f;
104247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return g;
104347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
104447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
104547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgdouble VirtualSocketServer::Evaluate(Function* f, double x) {
104647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Function::iterator iter =
104747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      std::lower_bound(f->begin(), f->end(), x, FunctionDomainCmp());
104847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (iter == f->begin()) {
104947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return (*f)[0].second;
105047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } else if (iter == f->end()) {
105147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    ASSERT(f->size() >= 1);
105247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return (*f)[f->size() - 1].second;
105347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } else if (iter->first == x) {
105447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return iter->second;
105547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } else {
105647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    double x1 = (iter - 1)->first;
105747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    double y1 = (iter - 1)->second;
105847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    double x2 = iter->first;
105947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    double y2 = iter->second;
106047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return y1 + (y2 - y1) * (x - x1) / (x2 - x1);
106147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
106247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
106347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
106447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool VirtualSocketServer::CanInteractWith(VirtualSocket* local,
106547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                          VirtualSocket* remote) {
106647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!local || !remote) {
106747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
106847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
106947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  IPAddress local_ip = local->GetLocalAddress().ipaddr();
107047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  IPAddress remote_ip = remote->GetLocalAddress().ipaddr();
107147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  IPAddress local_normalized = local_ip.Normalized();
107247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  IPAddress remote_normalized = remote_ip.Normalized();
107347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Check if the addresses are the same family after Normalization (turns
107447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // mapped IPv6 address into IPv4 addresses).
107547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // This will stop unmapped V6 addresses from talking to mapped V6 addresses.
107647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (local_normalized.family() == remote_normalized.family()) {
107747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return true;
107847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
107947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
108047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // If ip1 is IPv4 and ip2 is :: and ip2 is not IPV6_V6ONLY.
108147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int remote_v6_only = 0;
108247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  remote->GetOption(Socket::OPT_IPV6_V6ONLY, &remote_v6_only);
108347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (local_ip.family() == AF_INET && !remote_v6_only && IPIsAny(remote_ip)) {
108447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return true;
108547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
108647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Same check, backwards.
108747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int local_v6_only = 0;
108847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  local->GetOption(Socket::OPT_IPV6_V6ONLY, &local_v6_only);
108947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (remote_ip.family() == AF_INET && !local_v6_only && IPIsAny(local_ip)) {
109047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return true;
109147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
109247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
109347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Check to see if either socket was explicitly bound to IPv6-any.
109447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // These sockets can talk with anyone.
109547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (local_ip.family() == AF_INET6 && local->was_any()) {
109647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return true;
109747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
109847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (remote_ip.family() == AF_INET6 && remote->was_any()) {
109947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return true;
110047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
110147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
110247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return false;
110347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
110447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
110547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}  // namespace rtc
1106