stunserver.h (3788B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 // Original author: ekr@rtfm.com 8 9 #ifndef stunserver_h__ 10 #define stunserver_h__ 11 12 #include <map> 13 #include <string> 14 15 #include "mozilla/UniquePtr.h" 16 #include "nsError.h" 17 18 typedef struct nr_stun_server_ctx_ nr_stun_server_ctx; 19 typedef struct nr_socket_ nr_socket; 20 typedef struct nr_local_addr_ nr_local_addr; 21 22 namespace mozilla { 23 24 class TestStunServer { 25 public: 26 // Generally, you should only call API in this class from the same thread that 27 // the initial |GetInstance| call was made from. 28 static TestStunServer* GetInstance(int address_family = AF_INET); 29 static void ShutdownInstance(); 30 // |ConfigurePort| will only have an effect if called before the first call 31 // to |GetInstance| (possibly following a |ShutdownInstance| call) 32 static void ConfigurePort(uint16_t port); 33 // AF_INET, AF_INET6 34 static UniquePtr<TestStunServer> Create(int address_family); 35 36 virtual ~TestStunServer(); 37 38 void SetActive(bool active); 39 void SetDelay(uint32_t delay_ms); 40 void SetDropInitialPackets(uint32_t count); 41 const std::string& addr() const { return listen_addr_; } 42 uint16_t port() const { return listen_port_; } 43 44 // These should only be called from the same thread as the initial 45 // |GetInstance| call. 46 nsresult SetResponseAddr(nr_transport_addr* addr); 47 nsresult SetResponseAddr(const std::string& addr, uint16_t port); 48 49 void Reset(); 50 51 static const size_t max_stun_message_size = 4096; 52 53 virtual nr_socket* GetReceivingSocket(NR_SOCKET s); 54 virtual nr_socket* GetSendingSocket(nr_socket* sock); 55 56 protected: 57 TestStunServer() 58 : listen_port_(0), 59 listen_sock_(nullptr), 60 send_sock_(nullptr), 61 stun_server_(nullptr), 62 active_(true), 63 delay_ms_(0), 64 initial_ct_(0), 65 response_addr_(nullptr), 66 timer_handle_(nullptr) {} 67 68 int SetInternalPort(nr_local_addr* addr, uint16_t port); 69 int Initialize(int address_family); 70 71 static void readable_cb(NR_SOCKET sock, int how, void* cb_arg); 72 73 private: 74 void Process(const uint8_t* msg, size_t len, nr_transport_addr* addr_in, 75 nr_socket* sock); 76 virtual int TryOpenListenSocket(nr_local_addr* addr, uint16_t port); 77 static void process_cb(NR_SOCKET sock, int how, void* cb_arg); 78 79 protected: 80 std::string listen_addr_; 81 uint16_t listen_port_; 82 nr_socket* listen_sock_; 83 nr_socket* send_sock_; 84 nr_stun_server_ctx* stun_server_; 85 86 private: 87 bool active_; 88 uint32_t delay_ms_; 89 uint32_t initial_ct_; 90 nr_transport_addr* response_addr_; 91 void* timer_handle_; 92 std::map<std::string, uint32_t> received_ct_; 93 94 static TestStunServer* instance; 95 static TestStunServer* instance6; 96 static uint16_t instance_port; 97 }; 98 99 class TestStunTcpServer : public TestStunServer { 100 public: 101 static TestStunTcpServer* GetInstance(int address_family); 102 static void ShutdownInstance(); 103 static void ConfigurePort(uint16_t port); 104 virtual ~TestStunTcpServer(); 105 106 virtual nr_socket* GetReceivingSocket(NR_SOCKET s); 107 virtual nr_socket* GetSendingSocket(nr_socket* sock); 108 109 protected: 110 TestStunTcpServer() = default; 111 static void accept_cb(NR_SOCKET sock, int how, void* cb_arg); 112 113 private: 114 virtual int TryOpenListenSocket(nr_local_addr* addr, uint16_t port); 115 static UniquePtr<TestStunTcpServer> Create(int address_family); 116 117 static TestStunTcpServer* instance; 118 static TestStunTcpServer* instance6; 119 static uint16_t instance_port; 120 121 std::map<NR_SOCKET, nr_socket*> connections_; 122 }; 123 } // End of namespace mozilla 124 #endif