1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #ifndef mozilla_net_SocketProcessHost_h
7 #define mozilla_net_SocketProcessHost_h
8 
9 #include "mozilla/UniquePtr.h"
10 #include "mozilla/ipc/GeckoChildProcessHost.h"
11 #include "mozilla/MemoryReportingProcess.h"
12 #include "mozilla/ipc/TaskFactory.h"
13 
14 namespace mozilla {
15 
16 #if defined(XP_LINUX) && defined(MOZ_SANDBOX)
17 class SandboxBroker;
18 #endif
19 
20 namespace net {
21 
22 class SocketProcessParent;
23 
24 // SocketProcessHost is the "parent process" container for a subprocess handle
25 // and IPC connection. It owns the parent process IPDL actor, which in this
26 // case, is a SocketProcessParent.
27 // SocketProcessHost is allocated and managed by nsIOService in parent process.
28 class SocketProcessHost final : public mozilla::ipc::GeckoChildProcessHost {
29   friend class SocketProcessParent;
30 
31  public:
32   class Listener {
33    public:
34     NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Listener)
35 
36     // Called when the process of launching the process is complete.
37     virtual void OnProcessLaunchComplete(SocketProcessHost* aHost,
38                                          bool aSucceeded) = 0;
39 
40     // Called when the channel is closed but Shutdown() is not invoked.
41     virtual void OnProcessUnexpectedShutdown(SocketProcessHost* aHost) = 0;
42 
43    protected:
44     virtual ~Listener() = default;
45   };
46 
47   explicit SocketProcessHost(Listener* listener);
48 
49   // Launch the socket process asynchronously.
50   // The OnProcessLaunchComplete listener callback will be invoked
51   // either when a connection has been established, or if a connection
52   // could not be established due to an asynchronous error.
53   bool Launch();
54 
55   // Inform the socket process that it should clean up its resources and shut
56   // down. This initiates an asynchronous shutdown sequence. After this method
57   // returns, it is safe for the caller to forget its pointer to the
58   // SocketProcessHost.
59   void Shutdown();
60 
61   // Return the actor for the top-level actor of the process. Return null if
62   // the process is not connected.
GetActor()63   SocketProcessParent* GetActor() const {
64     MOZ_ASSERT(NS_IsMainThread());
65 
66     return mSocketProcessParent.get();
67   }
68 
IsConnected()69   bool IsConnected() const {
70     MOZ_ASSERT(NS_IsMainThread());
71 
72     return !!mSocketProcessParent;
73   }
74 
75   // Called on the IO thread.
76   void OnChannelConnected(int32_t peer_pid) override;
77   void OnChannelError() override;
78 
79 #if defined(XP_MACOSX) && defined(MOZ_SANDBOX)
80   // Return the sandbox type to be used with this process type.
81   static MacSandboxType GetMacSandboxType();
82 #endif
83 
84  private:
85   ~SocketProcessHost();
86 
87   // Called on the main thread.
88   void OnChannelConnectedTask();
89   void OnChannelErrorTask();
90 
91   // Called on the main thread after a connection has been established.
92   void InitAfterConnect(bool aSucceeded);
93 
94   // Called on the main thread when the mSocketParent actor is shutting down.
95   void OnChannelClosed();
96 
97   void DestroyProcess();
98 
99 #if defined(XP_MACOSX) && defined(MOZ_SANDBOX)
100   static bool sLaunchWithMacSandbox;
101 
102   // Sandbox the Socket process at launch for all instances
IsMacSandboxLaunchEnabled()103   bool IsMacSandboxLaunchEnabled() override { return sLaunchWithMacSandbox; }
104 
105   // Override so we can turn on Socket process-specific sandbox logging
106   bool FillMacSandboxInfo(MacSandboxInfo& aInfo) override;
107 #endif
108 
109   DISALLOW_COPY_AND_ASSIGN(SocketProcessHost);
110 
111   RefPtr<Listener> mListener;
112   mozilla::ipc::TaskFactory<SocketProcessHost> mTaskFactory;
113 
114   enum class LaunchPhase { Unlaunched, Waiting, Complete };
115   LaunchPhase mLaunchPhase;
116 
117   UniquePtr<SocketProcessParent> mSocketProcessParent;
118   // mShutdownRequested is set to true only when Shutdown() is called.
119   // If mShutdownRequested is false and the IPC channel is closed,
120   // OnProcessUnexpectedShutdown will be invoked.
121   bool mShutdownRequested;
122   bool mChannelClosed;
123 
124 #if defined(XP_LINUX) && defined(MOZ_SANDBOX)
125   UniquePtr<SandboxBroker> mSandboxBroker;
126 #endif
127 };
128 
129 class SocketProcessMemoryReporter : public MemoryReportingProcess {
130  public:
131   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SocketProcessMemoryReporter, override)
132 
133   SocketProcessMemoryReporter() = default;
134 
135   bool IsAlive() const override;
136 
137   bool SendRequestMemoryReport(
138       const uint32_t& aGeneration, const bool& aAnonymize,
139       const bool& aMinimizeMemoryUsage,
140       const Maybe<mozilla::ipc::FileDescriptor>& aDMDFile) override;
141 
142   int32_t Pid() const override;
143 
144  protected:
145   virtual ~SocketProcessMemoryReporter() = default;
146 };
147 
148 }  // namespace net
149 }  // namespace mozilla
150 
151 #endif  // mozilla_net_SocketProcessHost_h
152