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