media/mtransport/nricectx.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* vim: set ts=2 et sw=2 tw=80: */
michael@0 3 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 // Original author: ekr@rtfm.com
michael@0 8
michael@0 9 // Some of this code is cut-and-pasted from nICEr. Copyright is:
michael@0 10
michael@0 11 /*
michael@0 12 Copyright (c) 2007, Adobe Systems, Incorporated
michael@0 13 All rights reserved.
michael@0 14
michael@0 15 Redistribution and use in source and binary forms, with or without
michael@0 16 modification, are permitted provided that the following conditions are
michael@0 17 met:
michael@0 18
michael@0 19 * Redistributions of source code must retain the above copyright
michael@0 20 notice, this list of conditions and the following disclaimer.
michael@0 21
michael@0 22 * Redistributions in binary form must reproduce the above copyright
michael@0 23 notice, this list of conditions and the following disclaimer in the
michael@0 24 documentation and/or other materials provided with the distribution.
michael@0 25
michael@0 26 * Neither the name of Adobe Systems, Network Resonance nor the names of its
michael@0 27 contributors may be used to endorse or promote products derived from
michael@0 28 this software without specific prior written permission.
michael@0 29
michael@0 30 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
michael@0 31 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
michael@0 32 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
michael@0 33 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
michael@0 34 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
michael@0 35 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
michael@0 36 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
michael@0 37 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
michael@0 38 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
michael@0 39 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
michael@0 40 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
michael@0 41 */
michael@0 42
michael@0 43 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 44 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
michael@0 45 * You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 46
michael@0 47 // Original author: ekr@rtfm.com
michael@0 48
michael@0 49 // This is a wrapper around the nICEr ICE stack
michael@0 50 #ifndef nricectx_h__
michael@0 51 #define nricectx_h__
michael@0 52
michael@0 53 #include <vector>
michael@0 54
michael@0 55 #include "sigslot.h"
michael@0 56
michael@0 57 #include "prnetdb.h"
michael@0 58
michael@0 59 #include "mozilla/RefPtr.h"
michael@0 60 #include "mozilla/Scoped.h"
michael@0 61 #include "nsAutoPtr.h"
michael@0 62 #include "nsIEventTarget.h"
michael@0 63 #include "nsITimer.h"
michael@0 64
michael@0 65 #include "m_cpp_utils.h"
michael@0 66
michael@0 67 typedef struct nr_ice_ctx_ nr_ice_ctx;
michael@0 68 typedef struct nr_ice_peer_ctx_ nr_ice_peer_ctx;
michael@0 69 typedef struct nr_ice_media_stream_ nr_ice_media_stream;
michael@0 70 typedef struct nr_ice_handler_ nr_ice_handler;
michael@0 71 typedef struct nr_ice_handler_vtbl_ nr_ice_handler_vtbl;
michael@0 72 typedef struct nr_ice_candidate_ nr_ice_candidate;
michael@0 73 typedef struct nr_ice_cand_pair_ nr_ice_cand_pair;
michael@0 74 typedef struct nr_ice_stun_server_ nr_ice_stun_server;
michael@0 75 typedef struct nr_ice_turn_server_ nr_ice_turn_server;
michael@0 76 typedef struct nr_resolver_ nr_resolver;
michael@0 77
michael@0 78 typedef void* NR_SOCKET;
michael@0 79
michael@0 80 namespace mozilla {
michael@0 81
michael@0 82 class NrIceMediaStream;
michael@0 83
michael@0 84 extern const char kNrIceTransportUdp[];
michael@0 85 extern const char kNrIceTransportTcp[];
michael@0 86
michael@0 87 class NrIceStunServer {
michael@0 88 public:
michael@0 89 NrIceStunServer(const PRNetAddr& addr) : has_addr_(true) {
michael@0 90 memcpy(&addr_, &addr, sizeof(addr));
michael@0 91 }
michael@0 92
michael@0 93 // The main function to use. Will take either an address or a hostname.
michael@0 94 static NrIceStunServer* Create(const std::string& addr, uint16_t port) {
michael@0 95 ScopedDeletePtr<NrIceStunServer> server(
michael@0 96 new NrIceStunServer());
michael@0 97
michael@0 98 nsresult rv = server->Init(addr, port);
michael@0 99 if (NS_FAILED(rv))
michael@0 100 return nullptr;
michael@0 101
michael@0 102 return server.forget();
michael@0 103 }
michael@0 104
michael@0 105 nsresult ToNicerStunStruct(nr_ice_stun_server* server,
michael@0 106 const std::string& transport =
michael@0 107 kNrIceTransportUdp) const;
michael@0 108
michael@0 109 protected:
michael@0 110 NrIceStunServer() : addr_() {}
michael@0 111
michael@0 112 nsresult Init(const std::string& addr, uint16_t port) {
michael@0 113 PRStatus status = PR_StringToNetAddr(addr.c_str(), &addr_);
michael@0 114 if (status == PR_SUCCESS) {
michael@0 115 // Parseable as an address
michael@0 116 addr_.inet.port = PR_htons(port);
michael@0 117 port_ = port;
michael@0 118 has_addr_ = true;
michael@0 119 return NS_OK;
michael@0 120 }
michael@0 121 else if (addr.size() < 256) {
michael@0 122 // Apparently this is a hostname.
michael@0 123 host_ = addr;
michael@0 124 port_ = port;
michael@0 125 has_addr_ = false;
michael@0 126 return NS_OK;
michael@0 127 }
michael@0 128
michael@0 129 return NS_ERROR_FAILURE;
michael@0 130 }
michael@0 131
michael@0 132 bool has_addr_;
michael@0 133 std::string host_;
michael@0 134 uint16_t port_;
michael@0 135 PRNetAddr addr_;
michael@0 136 };
michael@0 137
michael@0 138 class NrIceTurnServer : public NrIceStunServer {
michael@0 139 public:
michael@0 140 static NrIceTurnServer *Create(const std::string& addr, uint16_t port,
michael@0 141 const std::string& username,
michael@0 142 const std::vector<unsigned char>& password,
michael@0 143 const char *transport = kNrIceTransportUdp) {
michael@0 144 ScopedDeletePtr<NrIceTurnServer> server(
michael@0 145 new NrIceTurnServer(username, password, transport));
michael@0 146
michael@0 147 nsresult rv = server->Init(addr, port);
michael@0 148 if (NS_FAILED(rv))
michael@0 149 return nullptr;
michael@0 150
michael@0 151 return server.forget();
michael@0 152 }
michael@0 153
michael@0 154 nsresult ToNicerTurnStruct(nr_ice_turn_server *server) const;
michael@0 155
michael@0 156 private:
michael@0 157 NrIceTurnServer(const std::string& username,
michael@0 158 const std::vector<unsigned char>& password,
michael@0 159 const char *transport) :
michael@0 160 username_(username), password_(password), transport_(transport) {}
michael@0 161
michael@0 162 std::string username_;
michael@0 163 std::vector<unsigned char> password_;
michael@0 164 std::string transport_;
michael@0 165 };
michael@0 166
michael@0 167 class NrIceCtx {
michael@0 168 public:
michael@0 169 enum ConnectionState { ICE_CTX_INIT,
michael@0 170 ICE_CTX_CHECKING,
michael@0 171 ICE_CTX_OPEN,
michael@0 172 ICE_CTX_FAILED
michael@0 173 };
michael@0 174
michael@0 175 enum GatheringState { ICE_CTX_GATHER_INIT,
michael@0 176 ICE_CTX_GATHER_STARTED,
michael@0 177 ICE_CTX_GATHER_COMPLETE
michael@0 178 };
michael@0 179
michael@0 180 enum Controlling { ICE_CONTROLLING,
michael@0 181 ICE_CONTROLLED
michael@0 182 };
michael@0 183
michael@0 184 static RefPtr<NrIceCtx> Create(const std::string& name,
michael@0 185 bool offerer,
michael@0 186 bool set_interface_priorities = true);
michael@0 187 virtual ~NrIceCtx();
michael@0 188
michael@0 189 nr_ice_ctx *ctx() { return ctx_; }
michael@0 190 nr_ice_peer_ctx *peer() { return peer_; }
michael@0 191
michael@0 192 // Testing only.
michael@0 193 void destroy_peer_ctx();
michael@0 194
michael@0 195 // Create a media stream
michael@0 196 RefPtr<NrIceMediaStream> CreateStream(const std::string& name,
michael@0 197 int components);
michael@0 198
michael@0 199 // The name of the ctx
michael@0 200 const std::string& name() const { return name_; }
michael@0 201
michael@0 202 // Current state
michael@0 203 ConnectionState connection_state() const {
michael@0 204 return connection_state_;
michael@0 205 }
michael@0 206
michael@0 207 // Current state
michael@0 208 GatheringState gathering_state() const {
michael@0 209 return gathering_state_;
michael@0 210 }
michael@0 211
michael@0 212 // Get the global attributes
michael@0 213 std::vector<std::string> GetGlobalAttributes();
michael@0 214
michael@0 215 // Set the other side's global attributes
michael@0 216 nsresult ParseGlobalAttributes(std::vector<std::string> attrs);
michael@0 217
michael@0 218 // Set whether we are controlling or not.
michael@0 219 nsresult SetControlling(Controlling controlling);
michael@0 220
michael@0 221 // Set the STUN servers. Must be called before StartGathering
michael@0 222 // (if at all).
michael@0 223 nsresult SetStunServers(const std::vector<NrIceStunServer>& stun_servers);
michael@0 224
michael@0 225 // Set the TURN servers. Must be called before StartGathering
michael@0 226 // (if at all).
michael@0 227 nsresult SetTurnServers(const std::vector<NrIceTurnServer>& turn_servers);
michael@0 228
michael@0 229 // Provide the resolution provider. Must be called before
michael@0 230 // StartGathering.
michael@0 231 nsresult SetResolver(nr_resolver *resolver);
michael@0 232
michael@0 233 // Start ICE gathering
michael@0 234 nsresult StartGathering();
michael@0 235
michael@0 236 // Start checking
michael@0 237 nsresult StartChecks();
michael@0 238
michael@0 239 // Finalize the ICE negotiation. I.e., there will be no
michael@0 240 // more forking.
michael@0 241 nsresult Finalize();
michael@0 242
michael@0 243 // Are we trickling?
michael@0 244 bool generating_trickle() const { return trickle_; }
michael@0 245
michael@0 246 // Signals to indicate events. API users can (and should)
michael@0 247 // register for these.
michael@0 248 sigslot::signal2<NrIceCtx*, NrIceCtx::GatheringState>
michael@0 249 SignalGatheringStateChange;
michael@0 250 sigslot::signal2<NrIceCtx*, NrIceCtx::ConnectionState>
michael@0 251 SignalConnectionStateChange;
michael@0 252
michael@0 253 // The thread to direct method calls to
michael@0 254 nsCOMPtr<nsIEventTarget> thread() { return sts_target_; }
michael@0 255
michael@0 256 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(NrIceCtx)
michael@0 257
michael@0 258 private:
michael@0 259 NrIceCtx(const std::string& name,
michael@0 260 bool offerer)
michael@0 261 : connection_state_(ICE_CTX_INIT),
michael@0 262 gathering_state_(ICE_CTX_GATHER_INIT),
michael@0 263 name_(name),
michael@0 264 offerer_(offerer),
michael@0 265 streams_(),
michael@0 266 ctx_(nullptr),
michael@0 267 peer_(nullptr),
michael@0 268 ice_handler_vtbl_(nullptr),
michael@0 269 ice_handler_(nullptr),
michael@0 270 trickle_(true) {
michael@0 271 // XXX: offerer_ will be used eventually; placate clang in the meantime.
michael@0 272 (void)offerer_;
michael@0 273 }
michael@0 274
michael@0 275 DISALLOW_COPY_ASSIGN(NrIceCtx);
michael@0 276
michael@0 277 // Callbacks for nICEr
michael@0 278 static void initialized_cb(NR_SOCKET s, int h, void *arg); // ICE initialized
michael@0 279
michael@0 280 // Handler implementation
michael@0 281 static int select_pair(void *obj,nr_ice_media_stream *stream,
michael@0 282 int component_id, nr_ice_cand_pair **potentials,
michael@0 283 int potential_ct);
michael@0 284 static int stream_ready(void *obj, nr_ice_media_stream *stream);
michael@0 285 static int stream_failed(void *obj, nr_ice_media_stream *stream);
michael@0 286 static int ice_completed(void *obj, nr_ice_peer_ctx *pctx);
michael@0 287 static int msg_recvd(void *obj, nr_ice_peer_ctx *pctx,
michael@0 288 nr_ice_media_stream *stream, int component_id,
michael@0 289 unsigned char *msg, int len);
michael@0 290 static void trickle_cb(void *arg, nr_ice_ctx *ctx, nr_ice_media_stream *stream,
michael@0 291 int component_id, nr_ice_candidate *candidate);
michael@0 292
michael@0 293 // Find a media stream by stream ptr. Gross
michael@0 294 RefPtr<NrIceMediaStream> FindStream(nr_ice_media_stream *stream);
michael@0 295
michael@0 296 // Set the state
michael@0 297 void SetConnectionState(ConnectionState state);
michael@0 298
michael@0 299 // Set the state
michael@0 300 void SetGatheringState(GatheringState state);
michael@0 301
michael@0 302 ConnectionState connection_state_;
michael@0 303 GatheringState gathering_state_;
michael@0 304 const std::string name_;
michael@0 305 bool offerer_;
michael@0 306 std::vector<RefPtr<NrIceMediaStream> > streams_;
michael@0 307 nr_ice_ctx *ctx_;
michael@0 308 nr_ice_peer_ctx *peer_;
michael@0 309 nr_ice_handler_vtbl* ice_handler_vtbl_; // Must be pointer
michael@0 310 nr_ice_handler* ice_handler_; // Must be pointer
michael@0 311 bool trickle_;
michael@0 312 nsCOMPtr<nsIEventTarget> sts_target_; // The thread to run on
michael@0 313 };
michael@0 314
michael@0 315
michael@0 316 } // close namespace
michael@0 317 #endif

mercurial