diff options
Diffstat (limited to 'third_party/libwebrtc/rtc_base/nat_socket_factory.h')
-rw-r--r-- | third_party/libwebrtc/rtc_base/nat_socket_factory.h | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/third_party/libwebrtc/rtc_base/nat_socket_factory.h b/third_party/libwebrtc/rtc_base/nat_socket_factory.h new file mode 100644 index 0000000000..0b301b5844 --- /dev/null +++ b/third_party/libwebrtc/rtc_base/nat_socket_factory.h @@ -0,0 +1,179 @@ +/* + * Copyright 2004 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef RTC_BASE_NAT_SOCKET_FACTORY_H_ +#define RTC_BASE_NAT_SOCKET_FACTORY_H_ + +#include <stddef.h> + +#include <map> +#include <memory> +#include <set> + +#include "rtc_base/nat_server.h" +#include "rtc_base/nat_types.h" +#include "rtc_base/socket.h" +#include "rtc_base/socket_address.h" +#include "rtc_base/socket_factory.h" +#include "rtc_base/socket_server.h" +#include "rtc_base/thread.h" + +namespace rtc { + +const size_t kNATEncodedIPv4AddressSize = 8U; +const size_t kNATEncodedIPv6AddressSize = 20U; + +// Used by the NAT socket implementation. +class NATInternalSocketFactory { + public: + virtual ~NATInternalSocketFactory() {} + virtual Socket* CreateInternalSocket(int family, + int type, + const SocketAddress& local_addr, + SocketAddress* nat_addr) = 0; +}; + +// Creates sockets that will send all traffic through a NAT, using an existing +// NATServer instance running at nat_addr. The actual data is sent using sockets +// from a socket factory, given to the constructor. +class NATSocketFactory : public SocketFactory, public NATInternalSocketFactory { + public: + NATSocketFactory(SocketFactory* factory, + const SocketAddress& nat_udp_addr, + const SocketAddress& nat_tcp_addr); + + NATSocketFactory(const NATSocketFactory&) = delete; + NATSocketFactory& operator=(const NATSocketFactory&) = delete; + + // SocketFactory implementation + Socket* CreateSocket(int family, int type) override; + + // NATInternalSocketFactory implementation + Socket* CreateInternalSocket(int family, + int type, + const SocketAddress& local_addr, + SocketAddress* nat_addr) override; + + private: + SocketFactory* factory_; + SocketAddress nat_udp_addr_; + SocketAddress nat_tcp_addr_; +}; + +// Creates sockets that will send traffic through a NAT depending on what +// address they bind to. This can be used to simulate a client on a NAT sending +// to a client that is not behind a NAT. +// Note that the internal addresses of clients must be unique. This is because +// there is only one socketserver per thread, and the Bind() address is used to +// figure out which NAT (if any) the socket should talk to. +// +// Example with 3 NATs (2 cascaded), and 3 clients. +// ss->AddTranslator("1.2.3.4", "192.168.0.1", NAT_ADDR_RESTRICTED); +// ss->AddTranslator("99.99.99.99", "10.0.0.1", NAT_SYMMETRIC)-> +// AddTranslator("10.0.0.2", "192.168.1.1", NAT_OPEN_CONE); +// ss->GetTranslator("1.2.3.4")->AddClient("1.2.3.4", "192.168.0.2"); +// ss->GetTranslator("99.99.99.99")->AddClient("10.0.0.3"); +// ss->GetTranslator("99.99.99.99")->GetTranslator("10.0.0.2")-> +// AddClient("192.168.1.2"); +class NATSocketServer : public SocketServer, public NATInternalSocketFactory { + public: + class Translator; + + // holds a list of NATs + class TranslatorMap : private std::map<SocketAddress, Translator*> { + public: + ~TranslatorMap(); + Translator* Get(const SocketAddress& ext_ip); + Translator* Add(const SocketAddress& ext_ip, Translator*); + void Remove(const SocketAddress& ext_ip); + Translator* FindClient(const SocketAddress& int_ip); + }; + + // a specific NAT + class Translator { + public: + Translator(NATSocketServer* server, + NATType type, + const SocketAddress& int_addr, + SocketFactory* ext_factory, + const SocketAddress& ext_addr); + ~Translator(); + + SocketFactory* internal_factory() { return internal_server_.get(); } + SocketAddress internal_udp_address() const { + return nat_server_->internal_udp_address(); + } + SocketAddress internal_tcp_address() const { + return SocketAddress(); // nat_server_->internal_tcp_address(); + } + + Translator* GetTranslator(const SocketAddress& ext_ip); + Translator* AddTranslator(const SocketAddress& ext_ip, + const SocketAddress& int_ip, + NATType type); + void RemoveTranslator(const SocketAddress& ext_ip); + + bool AddClient(const SocketAddress& int_ip); + void RemoveClient(const SocketAddress& int_ip); + + // Looks for the specified client in this or a child NAT. + Translator* FindClient(const SocketAddress& int_ip); + + private: + NATSocketServer* server_; + std::unique_ptr<SocketServer> internal_server_; + std::unique_ptr<NATServer> nat_server_; + TranslatorMap nats_; + std::set<SocketAddress> clients_; + }; + + explicit NATSocketServer(SocketServer* ss); + + NATSocketServer(const NATSocketServer&) = delete; + NATSocketServer& operator=(const NATSocketServer&) = delete; + + SocketServer* socketserver() { return server_; } + Thread* queue() { return msg_queue_; } + + Translator* GetTranslator(const SocketAddress& ext_ip); + Translator* AddTranslator(const SocketAddress& ext_ip, + const SocketAddress& int_ip, + NATType type); + void RemoveTranslator(const SocketAddress& ext_ip); + + // SocketServer implementation + Socket* CreateSocket(int family, int type) override; + + void SetMessageQueue(Thread* queue) override; + bool Wait(webrtc::TimeDelta max_wait_duration, bool process_io) override; + void WakeUp() override; + + // NATInternalSocketFactory implementation + Socket* CreateInternalSocket(int family, + int type, + const SocketAddress& local_addr, + SocketAddress* nat_addr) override; + + private: + SocketServer* server_; + Thread* msg_queue_; + TranslatorMap nats_; +}; + +// Free-standing NAT helper functions. +size_t PackAddressForNAT(char* buf, + size_t buf_size, + const SocketAddress& remote_addr); +size_t UnpackAddressFromNAT(const char* buf, + size_t buf_size, + SocketAddress* remote_addr); +} // namespace rtc + +#endif // RTC_BASE_NAT_SOCKET_FACTORY_H_ |