michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* vim: set ts=2 et sw=2 tw=80: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this file, michael@0: * You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: // Original author: ekr@rtfm.com michael@0: michael@0: #ifndef stunserver_h__ michael@0: #define stunserver_h__ michael@0: michael@0: #include michael@0: #include michael@0: #include "prio.h" michael@0: #include "nsError.h" michael@0: michael@0: typedef struct nr_stun_server_ctx_ nr_stun_server_ctx; michael@0: typedef struct nr_socket_ nr_socket; michael@0: typedef struct nr_local_addr_ nr_local_addr; michael@0: michael@0: namespace mozilla { michael@0: michael@0: class TestStunServer { michael@0: public: michael@0: // Generally, you should only call API in this class from the same thread that michael@0: // the initial |GetInstance| call was made from. michael@0: static TestStunServer *GetInstance(); michael@0: static void ShutdownInstance(); michael@0: // |ConfigurePort| will only have an effect if called before the first call michael@0: // to |GetInstance| (possibly following a |ShutdownInstance| call) michael@0: static void ConfigurePort(uint16_t port); michael@0: static TestStunServer *Create(); michael@0: michael@0: ~TestStunServer(); michael@0: michael@0: void SetActive(bool active); michael@0: void SetDelay(uint32_t delay_ms); michael@0: void SetDropInitialPackets(uint32_t count); michael@0: const std::string& addr() const { return listen_addr_; } michael@0: uint16_t port() const { return listen_port_; } michael@0: michael@0: // These should only be called from the same thread as the initial michael@0: // |GetInstance| call. michael@0: nsresult SetResponseAddr(nr_transport_addr *addr); michael@0: nsresult SetResponseAddr(const std::string& addr, uint16_t port); michael@0: michael@0: void Reset(); michael@0: michael@0: private: michael@0: TestStunServer() michael@0: : listen_sock_(nullptr), michael@0: send_sock_(nullptr), michael@0: stun_server_(nullptr), michael@0: active_(true), michael@0: delay_ms_(0), michael@0: initial_ct_(0), michael@0: response_addr_(nullptr), michael@0: timer_handle_(nullptr), michael@0: listen_port_(0) {} michael@0: michael@0: void Process(const uint8_t *msg, size_t len, nr_transport_addr *addr_in); michael@0: int TryOpenListenSocket(nr_local_addr* addr, uint16_t port); michael@0: michael@0: static void readable_cb(NR_SOCKET sock, int how, void *cb_arg); michael@0: static void process_cb(NR_SOCKET sock, int how, void *cb_arg); michael@0: michael@0: nr_socket *listen_sock_; michael@0: nr_socket *send_sock_; michael@0: nr_stun_server_ctx *stun_server_; michael@0: bool active_; michael@0: uint32_t delay_ms_; michael@0: uint32_t initial_ct_; michael@0: nr_transport_addr *response_addr_; michael@0: void *timer_handle_; michael@0: std::map received_ct_; michael@0: std::string listen_addr_; michael@0: uint16_t listen_port_; michael@0: michael@0: static TestStunServer* instance; michael@0: static uint16_t instance_port; michael@0: }; michael@0: michael@0: } // End of namespace mozilla michael@0: michael@0: #endif