1f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org/*
2f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
3f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *
4f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  Use of this source code is governed by a BSD-style license
5f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  that can be found in the LICENSE file in the root of the source
6f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  tree. An additional intellectual property rights grant can be found
7f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  in the file PATENTS.  All contributing project authors may
8f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org */
10f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
11f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/natsocketfactory.h"
12f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
135237aaf243d29732f59557361b7a993c0a18cf0etfarina#include "webrtc/base/arraysize.h"
14f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/logging.h"
15f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/natserver.h"
16f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/virtualsocketserver.h"
17f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
18f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgnamespace rtc {
19f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
20f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Packs the given socketaddress into the buffer in buf, in the quasi-STUN
21f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// format that the natserver uses.
22f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Returns 0 if an invalid address is passed.
23f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgsize_t PackAddressForNAT(char* buf, size_t buf_size,
24f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                         const SocketAddress& remote_addr) {
25f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  const IPAddress& ip = remote_addr.ipaddr();
26f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  int family = ip.family();
27f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  buf[0] = 0;
28f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  buf[1] = family;
29f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Writes the port.
300c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  *(reinterpret_cast<uint16_t*>(&buf[2])) = HostToNetwork16(remote_addr.port());
31f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (family == AF_INET) {
32f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ASSERT(buf_size >= kNATEncodedIPv4AddressSize);
33f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    in_addr v4addr = ip.ipv4_address();
34f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    memcpy(&buf[4], &v4addr, kNATEncodedIPv4AddressSize - 4);
35f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return kNATEncodedIPv4AddressSize;
36f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  } else if (family == AF_INET6) {
37f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ASSERT(buf_size >= kNATEncodedIPv6AddressSize);
38f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    in6_addr v6addr = ip.ipv6_address();
39f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    memcpy(&buf[4], &v6addr, kNATEncodedIPv6AddressSize - 4);
40f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return kNATEncodedIPv6AddressSize;
41f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
42f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return 0U;
43f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
44f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
45f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Decodes the remote address from a packet that has been encoded with the nat's
46f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// quasi-STUN format. Returns the length of the address (i.e., the offset into
47f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// data where the original packet starts).
48f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgsize_t UnpackAddressFromNAT(const char* buf, size_t buf_size,
49f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                            SocketAddress* remote_addr) {
50f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT(buf_size >= 8);
51f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  ASSERT(buf[0] == 0);
52f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  int family = buf[1];
530c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  uint16_t port =
540c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström      NetworkToHost16(*(reinterpret_cast<const uint16_t*>(&buf[2])));
55f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (family == AF_INET) {
56f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    const in_addr* v4addr = reinterpret_cast<const in_addr*>(&buf[4]);
57f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    *remote_addr = SocketAddress(IPAddress(*v4addr), port);
58f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return kNATEncodedIPv4AddressSize;
59f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  } else if (family == AF_INET6) {
60f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ASSERT(buf_size >= 20);
61f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    const in6_addr* v6addr = reinterpret_cast<const in6_addr*>(&buf[4]);
62f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    *remote_addr = SocketAddress(IPAddress(*v6addr), port);
63f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return kNATEncodedIPv6AddressSize;
64f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
65f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return 0U;
66f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
67f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
68f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
69f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// NATSocket
70f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgclass NATSocket : public AsyncSocket, public sigslot::has_slots<> {
71f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org public:
72f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  explicit NATSocket(NATInternalSocketFactory* sf, int family, int type)
73f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      : sf_(sf), family_(family), type_(type), connected_(false),
74f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        socket_(NULL), buf_(NULL), size_(0) {
75f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
76f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
7767186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.org  ~NATSocket() override {
78f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    delete socket_;
79f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    delete[] buf_;
80f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
81f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
8267186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.org  SocketAddress GetLocalAddress() const override {
83f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return (socket_) ? socket_->GetLocalAddress() : SocketAddress();
84f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
85f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
8667186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.org  SocketAddress GetRemoteAddress() const override {
87f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return remote_addr_;  // will be NIL if not connected
88f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
89f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
9067186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.org  int Bind(const SocketAddress& addr) override {
91f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (socket_) {  // already bound, bubble up error
92f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return -1;
93f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    }
94f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
95f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    int result;
96f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    socket_ = sf_->CreateInternalSocket(family_, type_, addr, &server_addr_);
97f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    result = (socket_) ? socket_->Bind(addr) : -1;
98f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (result >= 0) {
99f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      socket_->SignalConnectEvent.connect(this, &NATSocket::OnConnectEvent);
100f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      socket_->SignalReadEvent.connect(this, &NATSocket::OnReadEvent);
101f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      socket_->SignalWriteEvent.connect(this, &NATSocket::OnWriteEvent);
102f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      socket_->SignalCloseEvent.connect(this, &NATSocket::OnCloseEvent);
103f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    } else {
104f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      server_addr_.Clear();
105f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      delete socket_;
106f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      socket_ = NULL;
107f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    }
108f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
109f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return result;
110f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
111f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
11267186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.org  int Connect(const SocketAddress& addr) override {
113f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (!socket_) {  // socket must be bound, for now
114f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return -1;
115f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    }
116f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
117f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    int result = 0;
118f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (type_ == SOCK_STREAM) {
119f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      result = socket_->Connect(server_addr_.IsNil() ? addr : server_addr_);
120f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    } else {
121f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      connected_ = true;
122f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    }
123f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
124f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (result >= 0) {
125f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      remote_addr_ = addr;
126f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    }
127f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
128f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return result;
129f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
130f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
13167186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.org  int Send(const void* data, size_t size) override {
132f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ASSERT(connected_);
133f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return SendTo(data, size, remote_addr_);
134f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
135f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
13667186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.org  int SendTo(const void* data,
13767186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.org             size_t size,
13867186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.org             const SocketAddress& addr) override {
139f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ASSERT(!connected_ || addr == remote_addr_);
140f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (server_addr_.IsNil() || type_ == SOCK_STREAM) {
141f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return socket_->SendTo(data, size, addr);
142f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    }
143f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // This array will be too large for IPv4 packets, but only by 12 bytes.
144f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    scoped_ptr<char[]> buf(new char[size + kNATEncodedIPv6AddressSize]);
145f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    size_t addrlength = PackAddressForNAT(buf.get(),
146f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                          size + kNATEncodedIPv6AddressSize,
147f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                          addr);
148f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    size_t encoded_size = size + addrlength;
149f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    memcpy(buf.get() + addrlength, data, size);
150f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    int result = socket_->SendTo(buf.get(), encoded_size, server_addr_);
151f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (result >= 0) {
152f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ASSERT(result == static_cast<int>(encoded_size));
153f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      result = result - static_cast<int>(addrlength);
154f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    }
155f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return result;
156f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
157f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
15867186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.org  int Recv(void* data, size_t size) override {
159f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    SocketAddress addr;
160f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return RecvFrom(data, size, &addr);
161f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
162f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
16367186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.org  int RecvFrom(void* data, size_t size, SocketAddress* out_addr) override {
164f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (server_addr_.IsNil() || type_ == SOCK_STREAM) {
165f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      return socket_->RecvFrom(data, size, out_addr);
166f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    }
167f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // Make sure we have enough room to read the requested amount plus the
168f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // largest possible header address.
169f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    SocketAddress remote_addr;
170f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    Grow(size + kNATEncodedIPv6AddressSize);
171f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
172f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // Read the packet from the socket.
173f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    int result = socket_->RecvFrom(buf_, size_, &remote_addr);
174f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (result >= 0) {
175f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ASSERT(remote_addr == server_addr_);
176f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
177f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      // TODO: we need better framing so we know how many bytes we can
178f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      // return before we need to read the next address. For UDP, this will be
179f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      // fine as long as the reader always reads everything in the packet.
180f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      ASSERT((size_t)result < size_);
181f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
182f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      // Decode the wire packet into the actual results.
183f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      SocketAddress real_remote_addr;
184c5d0d95fd8957a7a6645b1196e5f1e9cee33525cdeadbeef      size_t addrlength = UnpackAddressFromNAT(buf_, result, &real_remote_addr);
185f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      memcpy(data, buf_ + addrlength, result - addrlength);
186f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
187f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      // Make sure this packet should be delivered before returning it.
188f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      if (!connected_ || (real_remote_addr == remote_addr_)) {
189f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        if (out_addr)
190f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org          *out_addr = real_remote_addr;
191f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        result = result - static_cast<int>(addrlength);
192f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      } else {
193f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        LOG(LS_ERROR) << "Dropping packet from unknown remote address: "
194f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                      << real_remote_addr.ToString();
195f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        result = 0;  // Tell the caller we didn't read anything
196f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      }
197f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    }
198f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
199f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return result;
200f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
201f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
20267186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.org  int Close() override {
203f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    int result = 0;
204f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (socket_) {
205f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      result = socket_->Close();
206f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      if (result >= 0) {
207f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        connected_ = false;
208f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        remote_addr_ = SocketAddress();
209f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        delete socket_;
210f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org        socket_ = NULL;
211f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      }
212f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    }
213f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return result;
214f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
215f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
21667186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.org  int Listen(int backlog) override { return socket_->Listen(backlog); }
21767186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.org  AsyncSocket* Accept(SocketAddress* paddr) override {
218f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return socket_->Accept(paddr);
219f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
22067186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.org  int GetError() const override { return socket_->GetError(); }
22167186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.org  void SetError(int error) override { socket_->SetError(error); }
22267186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.org  ConnState GetState() const override {
223f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return connected_ ? CS_CONNECTED : CS_CLOSED;
224f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
2250c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström  int EstimateMTU(uint16_t* mtu) override { return socket_->EstimateMTU(mtu); }
22667186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.org  int GetOption(Option opt, int* value) override {
227f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return socket_->GetOption(opt, value);
228f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
22967186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.org  int SetOption(Option opt, int value) override {
230f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return socket_->SetOption(opt, value);
231f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
232f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
233f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  void OnConnectEvent(AsyncSocket* socket) {
234c5d0d95fd8957a7a6645b1196e5f1e9cee33525cdeadbeef    // If we're NATed, we need to send a message with the real addr to use.
235f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ASSERT(socket == socket_);
236f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (server_addr_.IsNil()) {
237f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      connected_ = true;
238f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      SignalConnectEvent(this);
239f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    } else {
240f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      SendConnectRequest();
241f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    }
242f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
243f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  void OnReadEvent(AsyncSocket* socket) {
244f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    // If we're NATed, we need to process the connect reply.
245f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ASSERT(socket == socket_);
246f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (type_ == SOCK_STREAM && !server_addr_.IsNil() && !connected_) {
247f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      HandleConnectReply();
248f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    } else {
249f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      SignalReadEvent(this);
250f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    }
251f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
252f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  void OnWriteEvent(AsyncSocket* socket) {
253f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ASSERT(socket == socket_);
254f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    SignalWriteEvent(this);
255f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
256f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  void OnCloseEvent(AsyncSocket* socket, int error) {
257f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    ASSERT(socket == socket_);
258f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    SignalCloseEvent(this, error);
259f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
260f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
261f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org private:
262f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Makes sure the buffer is at least the given size.
263f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  void Grow(size_t new_size) {
264f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (size_ < new_size) {
265f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      delete[] buf_;
266f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      size_ = new_size;
267f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      buf_ = new char[size_];
268f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    }
269f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
270f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
271f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Sends the destination address to the server to tell it to connect.
272f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  void SendConnectRequest() {
273c5d0d95fd8957a7a6645b1196e5f1e9cee33525cdeadbeef    char buf[kNATEncodedIPv6AddressSize];
2745237aaf243d29732f59557361b7a993c0a18cf0etfarina    size_t length = PackAddressForNAT(buf, arraysize(buf), remote_addr_);
275f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    socket_->Send(buf, length);
276f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
277f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
278f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Handles the byte sent back from the server and fires the appropriate event.
279f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  void HandleConnectReply() {
280f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    char code;
281f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    socket_->Recv(&code, sizeof(code));
282f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    if (code == 0) {
283c5d0d95fd8957a7a6645b1196e5f1e9cee33525cdeadbeef      connected_ = true;
284f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      SignalConnectEvent(this);
285f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    } else {
286f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      Close();
287f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      SignalCloseEvent(this, code);
288f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    }
289f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
290f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
291f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  NATInternalSocketFactory* sf_;
292f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  int family_;
293f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  int type_;
294f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  bool connected_;
295f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SocketAddress remote_addr_;
296f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  SocketAddress server_addr_;  // address of the NAT server
297f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  AsyncSocket* socket_;
298f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  char* buf_;
299f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  size_t size_;
300f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org};
301f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
302f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// NATSocketFactory
303f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgNATSocketFactory::NATSocketFactory(SocketFactory* factory,
304c5d0d95fd8957a7a6645b1196e5f1e9cee33525cdeadbeef                                   const SocketAddress& nat_udp_addr,
305c5d0d95fd8957a7a6645b1196e5f1e9cee33525cdeadbeef                                   const SocketAddress& nat_tcp_addr)
306c5d0d95fd8957a7a6645b1196e5f1e9cee33525cdeadbeef    : factory_(factory), nat_udp_addr_(nat_udp_addr),
307c5d0d95fd8957a7a6645b1196e5f1e9cee33525cdeadbeef      nat_tcp_addr_(nat_tcp_addr) {
308f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
309f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
310f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgSocket* NATSocketFactory::CreateSocket(int type) {
311f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return CreateSocket(AF_INET, type);
312f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
313f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
314f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgSocket* NATSocketFactory::CreateSocket(int family, int type) {
315f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return new NATSocket(this, family, type);
316f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
317f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
318f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgAsyncSocket* NATSocketFactory::CreateAsyncSocket(int type) {
319f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return CreateAsyncSocket(AF_INET, type);
320f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
321f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
322f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgAsyncSocket* NATSocketFactory::CreateAsyncSocket(int family, int type) {
323f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return new NATSocket(this, family, type);
324f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
325f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
326f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgAsyncSocket* NATSocketFactory::CreateInternalSocket(int family, int type,
327f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    const SocketAddress& local_addr, SocketAddress* nat_addr) {
328c5d0d95fd8957a7a6645b1196e5f1e9cee33525cdeadbeef  if (type == SOCK_STREAM) {
329c5d0d95fd8957a7a6645b1196e5f1e9cee33525cdeadbeef    *nat_addr = nat_tcp_addr_;
330c5d0d95fd8957a7a6645b1196e5f1e9cee33525cdeadbeef  } else {
331c5d0d95fd8957a7a6645b1196e5f1e9cee33525cdeadbeef    *nat_addr = nat_udp_addr_;
332c5d0d95fd8957a7a6645b1196e5f1e9cee33525cdeadbeef  }
333f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return factory_->CreateAsyncSocket(family, type);
334f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
335f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
336f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// NATSocketServer
337f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgNATSocketServer::NATSocketServer(SocketServer* server)
338f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    : server_(server), msg_queue_(NULL) {
339f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
340f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
341f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgNATSocketServer::Translator* NATSocketServer::GetTranslator(
342f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    const SocketAddress& ext_ip) {
343f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return nats_.Get(ext_ip);
344f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
345f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
346f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgNATSocketServer::Translator* NATSocketServer::AddTranslator(
347f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    const SocketAddress& ext_ip, const SocketAddress& int_ip, NATType type) {
348f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Fail if a translator already exists with this extternal address.
349f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (nats_.Get(ext_ip))
350f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return NULL;
351f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
352f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return nats_.Add(ext_ip, new Translator(this, type, int_ip, server_, ext_ip));
353f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
354f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
355f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid NATSocketServer::RemoveTranslator(
356f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    const SocketAddress& ext_ip) {
357f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  nats_.Remove(ext_ip);
358f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
359f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
360f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgSocket* NATSocketServer::CreateSocket(int type) {
361f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return CreateSocket(AF_INET, type);
362f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
363f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
364f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgSocket* NATSocketServer::CreateSocket(int family, int type) {
365f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return new NATSocket(this, family, type);
366f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
367f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
368f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgAsyncSocket* NATSocketServer::CreateAsyncSocket(int type) {
369f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return CreateAsyncSocket(AF_INET, type);
370f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
371f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
372f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgAsyncSocket* NATSocketServer::CreateAsyncSocket(int family, int type) {
373f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return new NATSocket(this, family, type);
374f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
375f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
37667186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.orgvoid NATSocketServer::SetMessageQueue(MessageQueue* queue) {
37767186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.org  msg_queue_ = queue;
37867186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.org  server_->SetMessageQueue(queue);
37967186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.org}
38067186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.org
38167186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.orgbool NATSocketServer::Wait(int cms, bool process_io) {
38267186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.org  return server_->Wait(cms, process_io);
38367186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.org}
38467186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.org
38567186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.orgvoid NATSocketServer::WakeUp() {
38667186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.org  server_->WakeUp();
38767186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.org}
38867186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.org
389f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgAsyncSocket* NATSocketServer::CreateInternalSocket(int family, int type,
390f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    const SocketAddress& local_addr, SocketAddress* nat_addr) {
391f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  AsyncSocket* socket = NULL;
392f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  Translator* nat = nats_.FindClient(local_addr);
393f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (nat) {
394f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    socket = nat->internal_factory()->CreateAsyncSocket(family, type);
395f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    *nat_addr = (type == SOCK_STREAM) ?
396c5d0d95fd8957a7a6645b1196e5f1e9cee33525cdeadbeef        nat->internal_tcp_address() : nat->internal_udp_address();
397f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  } else {
398f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    socket = server_->CreateAsyncSocket(family, type);
399f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
400f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return socket;
401f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
402f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
403f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// NATSocketServer::Translator
404f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgNATSocketServer::Translator::Translator(
405f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    NATSocketServer* server, NATType type, const SocketAddress& int_ip,
406f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    SocketFactory* ext_factory, const SocketAddress& ext_ip)
407f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    : server_(server) {
408f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Create a new private network, and a NATServer running on the private
409f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // network that bridges to the external network. Also tell the private
410f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // network to use the same message queue as us.
411f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  VirtualSocketServer* internal_server = new VirtualSocketServer(server_);
412f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  internal_server->SetMessageQueue(server_->queue());
413f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  internal_factory_.reset(internal_server);
414c5d0d95fd8957a7a6645b1196e5f1e9cee33525cdeadbeef  nat_server_.reset(new NATServer(type, internal_server, int_ip, int_ip,
415f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                                  ext_factory, ext_ip));
416f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
417f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
41867186fe00cc68cbe03aa66d17fb4962458ca96d2kwiberg@webrtc.orgNATSocketServer::Translator::~Translator() = default;
419f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
420f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgNATSocketServer::Translator* NATSocketServer::Translator::GetTranslator(
421f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    const SocketAddress& ext_ip) {
422f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return nats_.Get(ext_ip);
423f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
424f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
425f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgNATSocketServer::Translator* NATSocketServer::Translator::AddTranslator(
426f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    const SocketAddress& ext_ip, const SocketAddress& int_ip, NATType type) {
427f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Fail if a translator already exists with this extternal address.
428f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (nats_.Get(ext_ip))
429f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return NULL;
430f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
431f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  AddClient(ext_ip);
432f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return nats_.Add(ext_ip,
433f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org                   new Translator(server_, type, int_ip, server_, ext_ip));
434f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
435f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid NATSocketServer::Translator::RemoveTranslator(
436f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    const SocketAddress& ext_ip) {
437f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  nats_.Remove(ext_ip);
438f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  RemoveClient(ext_ip);
439f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
440f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
441f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgbool NATSocketServer::Translator::AddClient(
442f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    const SocketAddress& int_ip) {
443f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // Fail if a client already exists with this internal address.
444f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (clients_.find(int_ip) != clients_.end())
445f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    return false;
446f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
447f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  clients_.insert(int_ip);
448f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return true;
449f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
450f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
451f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid NATSocketServer::Translator::RemoveClient(
452f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    const SocketAddress& int_ip) {
453f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  std::set<SocketAddress>::iterator it = clients_.find(int_ip);
454f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (it != clients_.end()) {
455f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    clients_.erase(it);
456f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
457f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
458f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
459f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgNATSocketServer::Translator* NATSocketServer::Translator::FindClient(
460f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    const SocketAddress& int_ip) {
461f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  // See if we have the requested IP, or any of our children do.
462f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return (clients_.find(int_ip) != clients_.end()) ?
463f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org      this : nats_.FindClient(int_ip);
464f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
465f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
466f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// NATSocketServer::TranslatorMap
467f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgNATSocketServer::TranslatorMap::~TranslatorMap() {
468f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  for (TranslatorMap::iterator it = begin(); it != end(); ++it) {
469f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    delete it->second;
470f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
471f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
472f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
473f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgNATSocketServer::Translator* NATSocketServer::TranslatorMap::Get(
474f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    const SocketAddress& ext_ip) {
475f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  TranslatorMap::iterator it = find(ext_ip);
476f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return (it != end()) ? it->second : NULL;
477f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
478f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
479f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgNATSocketServer::Translator* NATSocketServer::TranslatorMap::Add(
480f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    const SocketAddress& ext_ip, Translator* nat) {
481f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  (*this)[ext_ip] = nat;
482f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return nat;
483f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
484f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
485f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgvoid NATSocketServer::TranslatorMap::Remove(
486f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    const SocketAddress& ext_ip) {
487f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  TranslatorMap::iterator it = find(ext_ip);
488f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  if (it != end()) {
489f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    delete it->second;
490f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    erase(it);
491f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
492f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
493f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
494f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgNATSocketServer::Translator* NATSocketServer::TranslatorMap::FindClient(
495f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    const SocketAddress& int_ip) {
496f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  Translator* nat = NULL;
497f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  for (TranslatorMap::iterator it = begin(); it != end() && !nat; ++it) {
498f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org    nat = it->second->FindClient(int_ip);
499f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  }
500f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org  return nat;
501f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}
502f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org
503f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}  // namespace rtc
504