Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/mozilla/dom/TCPSocket.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=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
#ifndef mozilla_dom_TCPSocket_h
8
#define mozilla_dom_TCPSocket_h
9
10
#include "mozilla/dom/TCPSocketBinding.h"
11
#include "mozilla/DOMEventTargetHelper.h"
12
#include "nsITransport.h"
13
#include "nsIStreamListener.h"
14
#include "nsIAsyncInputStream.h"
15
#include "nsISupportsImpl.h"
16
#include "nsIObserver.h"
17
#include "nsWeakReference.h"
18
#include "nsITCPSocketCallback.h"
19
#include "js/RootingAPI.h"
20
21
class nsISocketTransport;
22
class nsIInputStreamPump;
23
class nsIScriptableInputStream;
24
class nsIBinaryInputStream;
25
class nsIMultiplexInputStream;
26
class nsIAsyncStreamCopier;
27
class nsIInputStream;
28
class nsINetworkInfo;
29
30
namespace mozilla {
31
class ErrorResult;
32
namespace dom {
33
34
struct ServerSocketOptions;
35
class TCPServerSocket;
36
class TCPSocketChild;
37
class TCPSocketParent;
38
39
// This interface is only used for legacy navigator.mozTCPSocket API compatibility.
40
class LegacyMozTCPSocket : public nsISupports
41
{
42
public:
43
  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
44
  NS_DECL_CYCLE_COLLECTION_CLASS(LegacyMozTCPSocket)
45
46
  explicit LegacyMozTCPSocket(nsPIDOMWindowInner* aWindow);
47
48
  already_AddRefed<TCPServerSocket>
49
  Listen(uint16_t aPort,
50
         const ServerSocketOptions& aOptions,
51
         uint16_t aBacklog,
52
         ErrorResult& aRv);
53
54
  already_AddRefed<TCPSocket>
55
  Open(const nsAString& aHost,
56
       uint16_t aPort,
57
       const SocketOptions& aOptions,
58
       ErrorResult& aRv);
59
60
  bool WrapObject(JSContext* aCx,
61
                  JS::Handle<JSObject*> aGivenProto,
62
                  JS::MutableHandle<JSObject*> aReflector);
63
64
private:
65
  virtual ~LegacyMozTCPSocket();
66
67
  nsCOMPtr<nsIGlobalObject> mGlobal;
68
};
69
70
class TCPSocket final : public DOMEventTargetHelper
71
                      , public nsIStreamListener
72
                      , public nsITransportEventSink
73
                      , public nsIInputStreamCallback
74
                      , public nsIObserver
75
                      , public nsSupportsWeakReference
76
                      , public nsITCPSocketCallback
77
{
78
public:
79
  TCPSocket(nsIGlobalObject* aGlobal, const nsAString& aHost, uint16_t aPort,
80
            bool aSsl, bool aUseArrayBuffers);
81
82
  NS_DECL_ISUPPORTS_INHERITED
83
  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(TCPSocket, DOMEventTargetHelper)
84
  NS_DECL_NSIREQUESTOBSERVER
85
  NS_DECL_NSISTREAMLISTENER
86
  NS_DECL_NSITRANSPORTEVENTSINK
87
  NS_DECL_NSIINPUTSTREAMCALLBACK
88
  NS_DECL_NSIOBSERVER
89
  NS_DECL_NSITCPSOCKETCALLBACK
90
91
  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
92
93
  static bool ShouldTCPSocketExist(JSContext* aCx, JSObject* aGlobal);
94
95
  void GetHost(nsAString& aHost);
96
  uint32_t Port();
97
  bool Ssl();
98
0
  uint64_t BufferedAmount() const { return mBufferedAmount; }
99
  void Suspend();
100
  void Resume(ErrorResult& aRv);
101
  void Close();
102
  void CloseImmediately();
103
  bool Send(JSContext* aCx, const nsACString& aData, ErrorResult& aRv);
104
  bool Send(JSContext* aCx,
105
            const ArrayBuffer& aData,
106
            uint32_t aByteOffset,
107
            const Optional<uint32_t>& aByteLength,
108
            ErrorResult& aRv);
109
  TCPReadyState ReadyState();
110
  TCPSocketBinaryType BinaryType();
111
  void UpgradeToSecure(ErrorResult& aRv);
112
113
  static already_AddRefed<TCPSocket>
114
  Constructor(const GlobalObject& aGlobal,
115
              const nsAString& aHost,
116
              uint16_t aPort,
117
              const SocketOptions& aOptions,
118
              ErrorResult& aRv);
119
120
  // Perform a send operation that's asssociated with a sequence number. Used in
121
  // IPC scenarios to track the number of bytes buffered at any given time.
122
  void SendWithTrackingNumber(const nsACString& aData,
123
                              const uint32_t& aTrackingNumber,
124
                              ErrorResult& aRv);
125
  void SendWithTrackingNumber(JSContext* aCx,
126
                              const ArrayBuffer& aData,
127
                              uint32_t aByteOffset,
128
                              const Optional<uint32_t>& aByteLength,
129
                              const uint32_t& aTrackingNumber,
130
                              ErrorResult& aRv);
131
  // Create a TCPSocket object from an existing low-level socket connection.
132
  // Used by the TCPServerSocket implementation when a new connection is accepted.
133
  static already_AddRefed<TCPSocket>
134
  CreateAcceptedSocket(nsIGlobalObject* aGlobal, nsISocketTransport* aTransport, bool aUseArrayBuffers);
135
  // Create a TCPSocket object from an existing child-side IPC actor.
136
  // Used by the TCPServerSocketChild implementation when a new connection is accepted.
137
  static already_AddRefed<TCPSocket>
138
  CreateAcceptedSocket(nsIGlobalObject* aGlobal, TCPSocketChild* aSocketBridge, bool aUseArrayBuffers);
139
140
  // Initialize this socket's associated IPC actor in the parent process.
141
  void SetSocketBridgeParent(TCPSocketParent* aBridgeParent);
142
143
  static bool SocketEnabled();
144
145
  IMPL_EVENT_HANDLER(open);
146
  IMPL_EVENT_HANDLER(drain);
147
  IMPL_EVENT_HANDLER(data);
148
  IMPL_EVENT_HANDLER(error);
149
  IMPL_EVENT_HANDLER(close);
150
151
  nsresult Init();
152
153
  // Inform this socket that a buffered send() has completed sending.
154
  void NotifyCopyComplete(nsresult aStatus);
155
156
  // Initialize this socket from a low-level connection that hasn't connected yet
157
  // (called from RecvOpenBind() in TCPSocketParent).
158
  nsresult InitWithUnconnectedTransport(nsISocketTransport* aTransport);
159
160
private:
161
  ~TCPSocket();
162
163
  // Initialize this socket with an existing IPC actor.
164
  void InitWithSocketChild(TCPSocketChild* aBridge);
165
  // Initialize this socket from an existing low-level connection.
166
  nsresult InitWithTransport(nsISocketTransport* aTransport);
167
  // Initialize the input/output streams for this socket object.
168
  nsresult CreateStream();
169
  // Initialize the asynchronous read operation from this socket's input stream.
170
  nsresult CreateInputStreamPump();
171
  // Send the contents of the provided input stream, which is assumed to be the given length
172
  // for reporting and buffering purposes.
173
  bool Send(nsIInputStream* aStream, uint32_t aByteLength);
174
  // Begin an asynchronous copy operation if one is not already in progress.
175
  nsresult EnsureCopying();
176
  // Enable TLS on this socket.
177
  void ActivateTLS();
178
  // Dispatch an error event if necessary, then dispatch a "close" event.
179
  nsresult MaybeReportErrorAndCloseIfOpen(nsresult status);
180
181
  // Helper for FireDataStringEvent/FireDataArrayEvent.
182
  nsresult FireDataEvent(JSContext* aCx, const nsAString& aType,
183
                         JS::Handle<JS::Value> aData);
184
  // Helper for Close/CloseImmediately
185
  void CloseHelper(bool waitForUnsentData);
186
187
  TCPReadyState mReadyState;
188
  // Whether to use strings or array buffers for the "data" event.
189
  bool mUseArrayBuffers;
190
  nsString mHost;
191
  uint16_t mPort;
192
  // Whether this socket is using a secure transport.
193
  bool mSsl;
194
195
  // The associated IPC actor in a child process.
196
  RefPtr<TCPSocketChild> mSocketBridgeChild;
197
  // The associated IPC actor in a parent process.
198
  RefPtr<TCPSocketParent> mSocketBridgeParent;
199
200
  // Raw socket streams
201
  nsCOMPtr<nsISocketTransport> mTransport;
202
  nsCOMPtr<nsIInputStream> mSocketInputStream;
203
  nsCOMPtr<nsIOutputStream> mSocketOutputStream;
204
205
  // Input stream machinery
206
  nsCOMPtr<nsIInputStreamPump> mInputStreamPump;
207
  nsCOMPtr<nsIScriptableInputStream> mInputStreamScriptable;
208
  nsCOMPtr<nsIBinaryInputStream> mInputStreamBinary;
209
210
  // Is there an async copy operation in progress?
211
  bool mAsyncCopierActive;
212
  // True if the buffer is full and a "drain" event is expected by the client.
213
  bool mWaitingForDrain;
214
215
  // The id of the window that created this socket.
216
  uint64_t mInnerWindowID;
217
218
  // The current number of buffered bytes. Only used in content processes when IPC is enabled.
219
  uint64_t mBufferedAmount;
220
221
  // The number of times this socket has had `Suspend` called without a corresponding `Resume`.
222
  uint32_t mSuspendCount;
223
224
  // The current sequence number (ie. number of send operations) that have been processed.
225
  // This is used in the IPC scenario by the child process to filter out outdated notifications
226
  // about the amount of buffered data present in the parent process.
227
  uint32_t mTrackingNumber;
228
229
  // True if this socket has been upgraded to secure after the initial connection,
230
  // but the actual upgrade is waiting for an in-progress copy operation to complete.
231
  bool mWaitingForStartTLS;
232
  // The buffered data awaiting the TLS upgrade to finish.
233
  nsTArray<nsCOMPtr<nsIInputStream>> mPendingDataAfterStartTLS;
234
235
  // The data to be sent.
236
  nsTArray<nsCOMPtr<nsIInputStream>> mPendingData;
237
238
  bool mObserversActive;
239
};
240
241
} // namespace dom
242
} // namespace mozilla
243
244
#endif // mozilla_dom_TCPSocket_h