| Index: webrtc/base/natserver.cc
|
| diff --git a/webrtc/base/natserver.cc b/webrtc/base/natserver.cc
|
| index 0ce04d70b3bf9995cfcb75e1c60c7ed0c45d71fd..b071e014dbdf37429c4f43cae2ef9200c8d9b371 100644
|
| --- a/webrtc/base/natserver.cc
|
| +++ b/webrtc/base/natserver.cc
|
| @@ -11,6 +11,7 @@
|
| #include "webrtc/base/natsocketfactory.h"
|
| #include "webrtc/base/natserver.h"
|
| #include "webrtc/base/logging.h"
|
| +#include "webrtc/base/socketadapters.h"
|
|
|
| namespace rtc {
|
|
|
| @@ -63,14 +64,77 @@ bool AddrCmp::operator()(
|
| return false;
|
| }
|
|
|
| +// Proxy socket that will capture the external destination address intended for
|
| +// a TCP connection to the NAT server.
|
| +class NATProxyServerSocket : public AsyncProxyServerSocket {
|
| + public:
|
| + NATProxyServerSocket(AsyncSocket* socket)
|
| + : AsyncProxyServerSocket(socket, kNATEncodedIPv6AddressSize) {
|
| + BufferInput(true);
|
| + }
|
| +
|
| + void SendConnectResult(int err, const SocketAddress& addr) override {
|
| + char code = err ? 1 : 0;
|
| + BufferedReadAdapter::DirectSend(&code, sizeof(char));
|
| + }
|
| +
|
| + protected:
|
| + void ProcessInput(char* data, size_t* len) override {
|
| + if (*len < 2) {
|
| + return;
|
| + }
|
| +
|
| + int family = data[1];
|
| + ASSERT(family == AF_INET || family == AF_INET6);
|
| + if ((family == AF_INET && *len < kNATEncodedIPv4AddressSize) ||
|
| + (family == AF_INET6 && *len < kNATEncodedIPv6AddressSize)) {
|
| + return;
|
| + }
|
| +
|
| + SocketAddress dest_addr;
|
| + size_t address_length = UnpackAddressFromNAT(data, *len, &dest_addr);
|
| +
|
| + *len -= address_length;
|
| + if (*len > 0) {
|
| + memmove(data, data + address_length, *len);
|
| + }
|
| +
|
| + bool remainder = (*len > 0);
|
| + BufferInput(false);
|
| + SignalConnectRequest(this, dest_addr);
|
| + if (remainder) {
|
| + SignalReadEvent(this);
|
| + }
|
| + }
|
| +
|
| +};
|
| +
|
| +class NATProxyServer : public ProxyServer {
|
| + public:
|
| + NATProxyServer(SocketFactory* int_factory, const SocketAddress& int_addr,
|
| + SocketFactory* ext_factory, const SocketAddress& ext_ip)
|
| + : ProxyServer(int_factory, int_addr, ext_factory, ext_ip) {
|
| + }
|
| +
|
| + protected:
|
| + AsyncProxyServerSocket* WrapSocket(AsyncSocket* socket) override {
|
| + return new NATProxyServerSocket(socket);
|
| + }
|
| +};
|
| +
|
| NATServer::NATServer(
|
| - NATType type, SocketFactory* internal, const SocketAddress& internal_addr,
|
| + NATType type, SocketFactory* internal,
|
| + const SocketAddress& internal_udp_addr,
|
| + const SocketAddress& internal_tcp_addr,
|
| SocketFactory* external, const SocketAddress& external_ip)
|
| : external_(external), external_ip_(external_ip.ipaddr(), 0) {
|
| nat_ = NAT::Create(type);
|
|
|
| - server_socket_ = AsyncUDPSocket::Create(internal, internal_addr);
|
| - server_socket_->SignalReadPacket.connect(this, &NATServer::OnInternalPacket);
|
| + udp_server_socket_ = AsyncUDPSocket::Create(internal, internal_udp_addr);
|
| + udp_server_socket_->SignalReadPacket.connect(this,
|
| + &NATServer::OnInternalUDPPacket);
|
| + tcp_proxy_server_ = new NATProxyServer(internal, internal_tcp_addr, external,
|
| + external_ip);
|
|
|
| int_map_ = new InternalMap(RouteCmp(nat_));
|
| ext_map_ = new ExternalMap();
|
| @@ -83,15 +147,15 @@ NATServer::~NATServer() {
|
| delete iter->second;
|
|
|
| delete nat_;
|
| - delete server_socket_;
|
| + delete udp_server_socket_;
|
| + delete tcp_proxy_server_;
|
| delete int_map_;
|
| delete ext_map_;
|
| }
|
|
|
| -void NATServer::OnInternalPacket(
|
| +void NATServer::OnInternalUDPPacket(
|
| AsyncPacketSocket* socket, const char* buf, size_t size,
|
| const SocketAddress& addr, const PacketTime& packet_time) {
|
| -
|
| // Read the intended destination from the wire.
|
| SocketAddress dest_addr;
|
| size_t length = UnpackAddressFromNAT(buf, size, &dest_addr);
|
| @@ -113,10 +177,9 @@ void NATServer::OnInternalPacket(
|
| iter->second->socket->SendTo(buf + length, size - length, dest_addr, options);
|
| }
|
|
|
| -void NATServer::OnExternalPacket(
|
| +void NATServer::OnExternalUDPPacket(
|
| AsyncPacketSocket* socket, const char* buf, size_t size,
|
| const SocketAddress& remote_addr, const PacketTime& packet_time) {
|
| -
|
| SocketAddress local_addr = socket->GetLocalAddress();
|
|
|
| // Find the translation for this addresses.
|
| @@ -139,8 +202,8 @@ void NATServer::OnExternalPacket(
|
| // Copy the data part after the address.
|
| rtc::PacketOptions options;
|
| memcpy(real_buf.get() + addrlength, buf, size);
|
| - server_socket_->SendTo(real_buf.get(), size + addrlength,
|
| - iter->second->route.source(), options);
|
| + udp_server_socket_->SendTo(real_buf.get(), size + addrlength,
|
| + iter->second->route.source(), options);
|
| }
|
|
|
| void NATServer::Translate(const SocketAddressPair& route) {
|
| @@ -154,7 +217,7 @@ void NATServer::Translate(const SocketAddressPair& route) {
|
| TransEntry* entry = new TransEntry(route, socket, nat_);
|
| (*int_map_)[route] = entry;
|
| (*ext_map_)[socket->GetLocalAddress()] = entry;
|
| - socket->SignalReadPacket.connect(this, &NATServer::OnExternalPacket);
|
| + socket->SignalReadPacket.connect(this, &NATServer::OnExternalUDPPacket);
|
| }
|
|
|
| bool NATServer::ShouldFilterOut(TransEntry* entry,
|
|
|