LCOV - code coverage report
Current view: top level - media/mtransport - nricectx.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 57 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 27 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : // Some of this code is cut-and-pasted from nICEr. Copyright is:
      10             : 
      11             : /*
      12             : Copyright (c) 2007, Adobe Systems, Incorporated
      13             : All rights reserved.
      14             : 
      15             : Redistribution and use in source and binary forms, with or without
      16             : modification, are permitted provided that the following conditions are
      17             : met:
      18             : 
      19             : * Redistributions of source code must retain the above copyright
      20             :   notice, this list of conditions and the following disclaimer.
      21             : 
      22             : * Redistributions in binary form must reproduce the above copyright
      23             :   notice, this list of conditions and the following disclaimer in the
      24             :   documentation and/or other materials provided with the distribution.
      25             : 
      26             : * Neither the name of Adobe Systems, Network Resonance nor the names of its
      27             :   contributors may be used to endorse or promote products derived from
      28             :   this software without specific prior written permission.
      29             : 
      30             : THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      31             : "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      32             : LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      33             : A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      34             : OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      35             : SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      36             : LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      37             : DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      38             : THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      39             : (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      40             : OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      41             : */
      42             : 
      43             : /* This Source Code Form is subject to the terms of the Mozilla Public
      44             :  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
      45             :  * You can obtain one at http://mozilla.org/MPL/2.0/. */
      46             : 
      47             : // Original author: ekr@rtfm.com
      48             : 
      49             : // This is a wrapper around the nICEr ICE stack
      50             : #ifndef nricectx_h__
      51             : #define nricectx_h__
      52             : 
      53             : #include <string>
      54             : #include <vector>
      55             : 
      56             : #include "sigslot.h"
      57             : 
      58             : #include "prnetdb.h"
      59             : 
      60             : #include "mozilla/RefPtr.h"
      61             : #include "mozilla/TimeStamp.h"
      62             : #include "mozilla/UniquePtr.h"
      63             : #include "nsAutoPtr.h"
      64             : #include "nsIEventTarget.h"
      65             : #include "nsITimer.h"
      66             : #include "nsTArray.h"
      67             : 
      68             : #include "m_cpp_utils.h"
      69             : #include "nricestunaddr.h"
      70             : 
      71             : typedef struct nr_ice_ctx_ nr_ice_ctx;
      72             : typedef struct nr_ice_peer_ctx_ nr_ice_peer_ctx;
      73             : typedef struct nr_ice_media_stream_ nr_ice_media_stream;
      74             : typedef struct nr_ice_handler_ nr_ice_handler;
      75             : typedef struct nr_ice_handler_vtbl_ nr_ice_handler_vtbl;
      76             : typedef struct nr_ice_candidate_ nr_ice_candidate;
      77             : typedef struct nr_ice_cand_pair_ nr_ice_cand_pair;
      78             : typedef struct nr_ice_stun_server_ nr_ice_stun_server;
      79             : typedef struct nr_ice_turn_server_ nr_ice_turn_server;
      80             : typedef struct nr_resolver_ nr_resolver;
      81             : typedef struct nr_proxy_tunnel_config_ nr_proxy_tunnel_config;
      82             : 
      83             : typedef void* NR_SOCKET;
      84             : 
      85             : namespace mozilla {
      86             : 
      87             : // Timestamps set whenever a packet is dropped due to global rate limiting
      88             : // (see nr_socket_prsock.cpp)
      89             : TimeStamp nr_socket_short_term_violation_time();
      90             : TimeStamp nr_socket_long_term_violation_time();
      91             : 
      92             : class NrIceMediaStream;
      93             : 
      94             : extern const char kNrIceTransportUdp[];
      95             : extern const char kNrIceTransportTcp[];
      96             : extern const char kNrIceTransportTls[];
      97             : 
      98           0 : class NrIceStunServer {
      99             :  public:
     100             :   explicit NrIceStunServer(const PRNetAddr& addr) : has_addr_(true) {
     101             :     memcpy(&addr_, &addr, sizeof(addr));
     102             :   }
     103             : 
     104             :    // The main function to use. Will take either an address or a hostname.
     105           0 :   static UniquePtr<NrIceStunServer> Create(const std::string& addr, uint16_t port,
     106             :       const char *transport = kNrIceTransportUdp) {
     107           0 :     UniquePtr<NrIceStunServer> server(new NrIceStunServer(transport));
     108             : 
     109           0 :     nsresult rv = server->Init(addr, port);
     110           0 :     if (NS_FAILED(rv))
     111           0 :       return nullptr;
     112             : 
     113           0 :     return server;
     114             :   }
     115             : 
     116             :   nsresult ToNicerStunStruct(nr_ice_stun_server* server) const;
     117             : 
     118             :  protected:
     119           0 :   explicit NrIceStunServer(const char *transport) :
     120           0 :       addr_(), transport_(transport) {}
     121             : 
     122           0 :   nsresult Init(const std::string& addr, uint16_t port) {
     123           0 :     PRStatus status = PR_StringToNetAddr(addr.c_str(), &addr_);
     124           0 :     if (status == PR_SUCCESS) {
     125             :       // Parseable as an address
     126           0 :       addr_.inet.port = PR_htons(port);
     127           0 :       port_ = port;
     128           0 :       has_addr_ = true;
     129           0 :       return NS_OK;
     130             :     }
     131           0 :     else if (addr.size() < 256) {
     132             :       // Apparently this is a hostname.
     133           0 :       host_ = addr;
     134           0 :       port_ = port;
     135           0 :       has_addr_ = false;
     136           0 :       return NS_OK;
     137             :     }
     138             : 
     139           0 :     return NS_ERROR_FAILURE;
     140             :   }
     141             : 
     142             :   bool has_addr_;
     143             :   std::string host_;
     144             :   uint16_t port_;
     145             :   PRNetAddr addr_;
     146             :   std::string transport_;
     147             : };
     148             : 
     149           0 : class NrIceTurnServer : public NrIceStunServer {
     150             :  public:
     151           0 :   static UniquePtr<NrIceTurnServer> Create(const std::string& addr, uint16_t port,
     152             :                                            const std::string& username,
     153             :                                            const std::vector<unsigned char>& password,
     154             :                                            const char *transport = kNrIceTransportUdp) {
     155           0 :     UniquePtr<NrIceTurnServer> server(new NrIceTurnServer(username, password, transport));
     156             : 
     157           0 :     nsresult rv = server->Init(addr, port);
     158           0 :     if (NS_FAILED(rv))
     159           0 :       return nullptr;
     160             : 
     161           0 :     return server;
     162             :   }
     163             : 
     164             :   nsresult ToNicerTurnStruct(nr_ice_turn_server *server) const;
     165             : 
     166             :  private:
     167           0 :   NrIceTurnServer(const std::string& username,
     168             :                   const std::vector<unsigned char>& password,
     169           0 :                   const char *transport) :
     170           0 :       NrIceStunServer(transport), username_(username), password_(password) {}
     171             : 
     172             :   std::string username_;
     173             :   std::vector<unsigned char> password_;
     174             : };
     175             : 
     176           0 : class NrIceProxyServer {
     177             :  public:
     178           0 :   NrIceProxyServer(const std::string& host, uint16_t port,
     179           0 :                    const std::string& alpn) :
     180           0 :     host_(host), port_(port), alpn_(alpn) {
     181           0 :   }
     182             : 
     183             :   NrIceProxyServer() : NrIceProxyServer("", 0, "") {}
     184             : 
     185           0 :   const std::string& host() const { return host_; }
     186           0 :   uint16_t port() const { return port_; }
     187             :   const std::string& alpn() const { return alpn_; }
     188             : 
     189             :  private:
     190             :   std::string host_;
     191             :   uint16_t port_;
     192             :   std::string alpn_;
     193             : };
     194             : 
     195             : class TestNat;
     196             : 
     197             : class NrIceStats {
     198             :  public:
     199             :   uint16_t stun_retransmits = 0;
     200             :   uint16_t turn_401s = 0;
     201             :   uint16_t turn_403s = 0;
     202             :   uint16_t turn_438s = 0;
     203             : };
     204             : 
     205             : class NrIceCtx {
     206             :  friend class NrIceCtxHandler;
     207             :  public:
     208             :   enum ConnectionState { ICE_CTX_INIT,
     209             :                          ICE_CTX_CHECKING,
     210             :                          ICE_CTX_CONNECTED,
     211             :                          ICE_CTX_COMPLETED,
     212             :                          ICE_CTX_FAILED,
     213             :                          ICE_CTX_DISCONNECTED,
     214             :                          ICE_CTX_CLOSED
     215             :   };
     216             : 
     217             :   enum GatheringState { ICE_CTX_GATHER_INIT,
     218             :                         ICE_CTX_GATHER_STARTED,
     219             :                         ICE_CTX_GATHER_COMPLETE
     220             :   };
     221             : 
     222             :   enum Controlling { ICE_CONTROLLING,
     223             :                      ICE_CONTROLLED
     224             :   };
     225             : 
     226             :   enum Policy { ICE_POLICY_RELAY,
     227             :                 ICE_POLICY_NO_HOST,
     228             :                 ICE_POLICY_ALL
     229             :   };
     230             : 
     231             :   // initialize ICE globals, crypto, and logging
     232             :   static void InitializeGlobals(bool allow_loopback = false,
     233             :                                 bool tcp_enabled = true,
     234             :                                 bool allow_link_local = false);
     235             :   static std::string GetNewUfrag();
     236             :   static std::string GetNewPwd();
     237             : 
     238             :   // static GetStunAddrs for use in parent process to support
     239             :   // sandboxing restrictions
     240             :   static nsTArray<NrIceStunAddr> GetStunAddrs();
     241             :   void SetStunAddrs(const nsTArray<NrIceStunAddr>& addrs);
     242             : 
     243             :   bool Initialize();
     244             :   bool Initialize(const std::string& ufrag, const std::string& pwd);
     245             : 
     246             :   int SetNat(const RefPtr<TestNat>& aNat);
     247             : 
     248             :   // Deinitialize all ICE global state. Used only for testing.
     249             :   static void internal_DeinitializeGlobal();
     250             : 
     251             :   // Divide some timers to faster testing. Used only for testing.
     252             :   void internal_SetTimerAccelarator(int divider);
     253             : 
     254           0 :   nr_ice_ctx *ctx() { return ctx_; }
     255           0 :   nr_ice_peer_ctx *peer() { return peer_; }
     256             : 
     257             :   // Testing only.
     258             :   void destroy_peer_ctx();
     259             : 
     260             :   void SetStream(size_t index, NrIceMediaStream* stream);
     261             : 
     262           0 :   RefPtr<NrIceMediaStream> GetStream(size_t index) {
     263           0 :     if (index < streams_.size()) {
     264           0 :       return streams_[index];
     265             :     }
     266           0 :     return nullptr;
     267             :   }
     268             : 
     269             :   // Some might be null
     270           0 :   size_t GetStreamCount() const
     271             :   {
     272           0 :     return streams_.size();
     273             :   }
     274             : 
     275             :   // The name of the ctx
     276           0 :   const std::string& name() const { return name_; }
     277             : 
     278             :   // Get ufrag and password.
     279             :   std::string ufrag() const;
     280             :   std::string pwd() const;
     281             : 
     282             :   // Current state
     283           0 :   ConnectionState connection_state() const {
     284           0 :     return connection_state_;
     285             :   }
     286             : 
     287             :   // Current state
     288           0 :   GatheringState gathering_state() const {
     289           0 :     return gathering_state_;
     290             :   }
     291             : 
     292             :   // Get the global attributes
     293             :   std::vector<std::string> GetGlobalAttributes();
     294             : 
     295             :   // Set the other side's global attributes
     296             :   nsresult ParseGlobalAttributes(std::vector<std::string> attrs);
     297             : 
     298             :   // Set whether we are controlling or not.
     299             :   nsresult SetControlling(Controlling controlling);
     300             : 
     301             :   Controlling GetControlling();
     302             : 
     303             :   // Set whether we're allowed to produce none, relay or all candidates.
     304             :   // TODO(jib@mozilla.com): Work out what change means mid-connection (1181768)
     305             :   nsresult SetPolicy(Policy policy);
     306             : 
     307           0 :   Policy policy() const {
     308           0 :     return policy_;
     309             :   }
     310             : 
     311             :   // Set the STUN servers. Must be called before StartGathering
     312             :   // (if at all).
     313             :   nsresult SetStunServers(const std::vector<NrIceStunServer>& stun_servers);
     314             : 
     315             :   // Set the TURN servers. Must be called before StartGathering
     316             :   // (if at all).
     317             :   nsresult SetTurnServers(const std::vector<NrIceTurnServer>& turn_servers);
     318             : 
     319             :   // Provide the resolution provider. Must be called before
     320             :   // StartGathering.
     321             :   nsresult SetResolver(nr_resolver *resolver);
     322             : 
     323             :   // Provide the proxy address. Must be called before
     324             :   // StartGathering.
     325             :   nsresult SetProxyServer(const NrIceProxyServer& proxy_server);
     326             : 
     327             :   // Start ICE gathering
     328             :   nsresult StartGathering(bool default_route_only, bool proxy_only);
     329             : 
     330             :   // Start checking
     331             :   nsresult StartChecks(bool offerer);
     332             : 
     333             :   // Notify that the network has gone online/offline
     334             :   void UpdateNetworkState(bool online);
     335             : 
     336             :   // Finalize the ICE negotiation. I.e., there will be no
     337             :   // more forking.
     338             :   nsresult Finalize();
     339             : 
     340             :   void AccumulateStats(const NrIceStats& stats);
     341             :   NrIceStats Destroy();
     342             : 
     343             :   // Are we trickling?
     344           0 :   bool generating_trickle() const { return trickle_; }
     345             : 
     346             :   // Signals to indicate events. API users can (and should)
     347             :   // register for these.
     348             :   sigslot::signal2<NrIceCtx*, NrIceCtx::GatheringState>
     349             :     SignalGatheringStateChange;
     350             :   sigslot::signal2<NrIceCtx*, NrIceCtx::ConnectionState>
     351             :     SignalConnectionStateChange;
     352             : 
     353             :   // The thread to direct method calls to
     354           0 :   nsCOMPtr<nsIEventTarget> thread() { return sts_target_; }
     355             : 
     356           0 :   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(NrIceCtx)
     357             : 
     358             : private:
     359             :   NrIceCtx(const std::string& name, Policy policy);
     360             : 
     361             :   virtual ~NrIceCtx();
     362             : 
     363             :   DISALLOW_COPY_ASSIGN(NrIceCtx);
     364             : 
     365             :   // Callbacks for nICEr
     366             :   static void gather_cb(NR_SOCKET s, int h, void *arg);  // ICE gather complete
     367             : 
     368             :   // Handler implementation
     369             :   static int select_pair(void *obj,nr_ice_media_stream *stream,
     370             :                          int component_id, nr_ice_cand_pair **potentials,
     371             :                          int potential_ct);
     372             :   static int stream_ready(void *obj, nr_ice_media_stream *stream);
     373             :   static int stream_failed(void *obj, nr_ice_media_stream *stream);
     374             :   static int ice_checking(void *obj, nr_ice_peer_ctx *pctx);
     375             :   static int ice_connected(void *obj, nr_ice_peer_ctx *pctx);
     376             :   static int ice_disconnected(void *obj, nr_ice_peer_ctx *pctx);
     377             :   static int msg_recvd(void *obj, nr_ice_peer_ctx *pctx,
     378             :                        nr_ice_media_stream *stream, int component_id,
     379             :                        unsigned char *msg, int len);
     380             :   static void trickle_cb(void *arg, nr_ice_ctx *ctx, nr_ice_media_stream *stream,
     381             :                          int component_id, nr_ice_candidate *candidate);
     382             : 
     383             :   // Find a media stream by stream ptr. Gross
     384             :   RefPtr<NrIceMediaStream> FindStream(nr_ice_media_stream *stream);
     385             : 
     386             :   // Set the state
     387             :   void SetConnectionState(ConnectionState state);
     388             : 
     389             :   // Set the state
     390             :   void SetGatheringState(GatheringState state);
     391             : 
     392             :   ConnectionState connection_state_;
     393             :   GatheringState gathering_state_;
     394             :   const std::string name_;
     395             :   bool offerer_;
     396             :   TimeStamp ice_start_time_;
     397             :   bool ice_controlling_set_;
     398             :   std::vector<RefPtr<NrIceMediaStream> > streams_;
     399             :   nr_ice_ctx *ctx_;
     400             :   nr_ice_peer_ctx *peer_;
     401             :   nr_ice_handler_vtbl* ice_handler_vtbl_;  // Must be pointer
     402             :   nr_ice_handler* ice_handler_;  // Must be pointer
     403             :   bool trickle_;
     404             :   nsCOMPtr<nsIEventTarget> sts_target_; // The thread to run on
     405             :   Policy policy_;
     406             :   RefPtr<TestNat> nat_;
     407             : };
     408             : 
     409             : 
     410             : }  // close namespace
     411             : #endif

Generated by: LCOV version 1.13