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