media/mtransport/transportlayerloopback.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 #ifndef transportlayerloopback_h__
michael@0 10 #define transportlayerloopback_h__
michael@0 11
michael@0 12 #include "nspr.h"
michael@0 13 #include "prio.h"
michael@0 14 #include "prlock.h"
michael@0 15
michael@0 16 #include <memory>
michael@0 17 #include <queue>
michael@0 18
michael@0 19
michael@0 20 #include "nsAutoPtr.h"
michael@0 21 #include "nsCOMPtr.h"
michael@0 22 #include "nsITimer.h"
michael@0 23
michael@0 24
michael@0 25 #include "m_cpp_utils.h"
michael@0 26 #include "transportflow.h"
michael@0 27 #include "transportlayer.h"
michael@0 28
michael@0 29 // A simple loopback transport layer that is used for testing.
michael@0 30 namespace mozilla {
michael@0 31
michael@0 32 class TransportLayerLoopback : public TransportLayer {
michael@0 33 public:
michael@0 34 TransportLayerLoopback() :
michael@0 35 peer_(nullptr),
michael@0 36 timer_(nullptr),
michael@0 37 packets_(),
michael@0 38 packets_lock_(nullptr),
michael@0 39 deliverer_(nullptr) {}
michael@0 40
michael@0 41 ~TransportLayerLoopback() {
michael@0 42 while (!packets_.empty()) {
michael@0 43 QueuedPacket *packet = packets_.front();
michael@0 44 packets_.pop();
michael@0 45 delete packet;
michael@0 46 }
michael@0 47 if (packets_lock_) {
michael@0 48 PR_DestroyLock(packets_lock_);
michael@0 49 }
michael@0 50 timer_->Cancel();
michael@0 51 deliverer_->Detach();
michael@0 52 }
michael@0 53
michael@0 54 // Init
michael@0 55 nsresult Init();
michael@0 56
michael@0 57 // Connect to the other side
michael@0 58 void Connect(TransportLayerLoopback* peer);
michael@0 59
michael@0 60 // Disconnect
michael@0 61 void Disconnect() {
michael@0 62 TransportLayerLoopback *peer = peer_;
michael@0 63
michael@0 64 peer_ = nullptr;
michael@0 65 if (peer) {
michael@0 66 peer->Disconnect();
michael@0 67 }
michael@0 68 }
michael@0 69
michael@0 70 // Overrides for TransportLayer
michael@0 71 virtual TransportResult SendPacket(const unsigned char *data, size_t len);
michael@0 72
michael@0 73 // Deliver queued packets
michael@0 74 void DeliverPackets();
michael@0 75
michael@0 76 TRANSPORT_LAYER_ID("loopback")
michael@0 77
michael@0 78 private:
michael@0 79 DISALLOW_COPY_ASSIGN(TransportLayerLoopback);
michael@0 80
michael@0 81 // A queued packet
michael@0 82 class QueuedPacket {
michael@0 83 public:
michael@0 84 QueuedPacket() : data_(nullptr), len_(0) {}
michael@0 85 ~QueuedPacket() {
michael@0 86 delete [] data_;
michael@0 87 }
michael@0 88
michael@0 89 void Assign(const unsigned char *data, size_t len) {
michael@0 90 data_ = new unsigned char[len];
michael@0 91 memcpy(static_cast<void *>(data_),
michael@0 92 static_cast<const void *>(data), len);
michael@0 93 len_ = len;
michael@0 94 }
michael@0 95
michael@0 96 const unsigned char *data() const { return data_; }
michael@0 97 size_t len() const { return len_; }
michael@0 98
michael@0 99 private:
michael@0 100 DISALLOW_COPY_ASSIGN(QueuedPacket);
michael@0 101
michael@0 102 unsigned char *data_;
michael@0 103 size_t len_;
michael@0 104 };
michael@0 105
michael@0 106 // A timer to deliver packets if some are available
michael@0 107 // Fires every 100 ms
michael@0 108 class Deliverer : public nsITimerCallback {
michael@0 109 public:
michael@0 110 Deliverer(TransportLayerLoopback *layer) :
michael@0 111 layer_(layer) {}
michael@0 112 virtual ~Deliverer() {
michael@0 113 }
michael@0 114 void Detach() {
michael@0 115 layer_ = nullptr;
michael@0 116 }
michael@0 117
michael@0 118 NS_DECL_THREADSAFE_ISUPPORTS
michael@0 119 NS_DECL_NSITIMERCALLBACK
michael@0 120
michael@0 121 private:
michael@0 122 DISALLOW_COPY_ASSIGN(Deliverer);
michael@0 123
michael@0 124 TransportLayerLoopback *layer_;
michael@0 125 };
michael@0 126
michael@0 127 // Queue a packet for delivery
michael@0 128 nsresult QueuePacket(const unsigned char *data, size_t len);
michael@0 129
michael@0 130 TransportLayerLoopback* peer_;
michael@0 131 nsCOMPtr<nsITimer> timer_;
michael@0 132 std::queue<QueuedPacket *> packets_;
michael@0 133 PRLock *packets_lock_;
michael@0 134 nsRefPtr<Deliverer> deliverer_;
michael@0 135 };
michael@0 136
michael@0 137 } // close namespace
michael@0 138 #endif

mercurial