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 #include "nsIScriptSecurityManager.h"
8 #include "TCPServerSocket.h"
9 #include "TCPServerSocketParent.h"
10 #include "nsJSUtils.h"
11 #include "TCPSocketParent.h"
12 #include "mozilla/Unused.h"
13 #include "mozilla/AppProcessChecker.h"
14 #include "mozilla/dom/ContentParent.h"
15 #include "mozilla/dom/TabParent.h"
16 
17 namespace mozilla {
18 namespace dom {
19 
NS_IMPL_CYCLE_COLLECTION(TCPServerSocketParent,mServerSocket)20 NS_IMPL_CYCLE_COLLECTION(TCPServerSocketParent, mServerSocket)
21 NS_IMPL_CYCLE_COLLECTING_ADDREF(TCPServerSocketParent)
22 NS_IMPL_CYCLE_COLLECTING_RELEASE(TCPServerSocketParent)
23 
24 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TCPServerSocketParent)
25   NS_INTERFACE_MAP_ENTRY(nsISupports)
26 NS_INTERFACE_MAP_END
27 
28 void
29 TCPServerSocketParent::ReleaseIPDLReference()
30 {
31   MOZ_ASSERT(mIPCOpen);
32   mIPCOpen = false;
33   this->Release();
34 }
35 
36 void
AddIPDLReference()37 TCPServerSocketParent::AddIPDLReference()
38 {
39   MOZ_ASSERT(!mIPCOpen);
40   mIPCOpen = true;
41   this->AddRef();
42 }
43 
TCPServerSocketParent(PNeckoParent * neckoParent,uint16_t aLocalPort,uint16_t aBacklog,bool aUseArrayBuffers)44 TCPServerSocketParent::TCPServerSocketParent(PNeckoParent* neckoParent,
45                                              uint16_t aLocalPort,
46                                              uint16_t aBacklog,
47                                              bool aUseArrayBuffers)
48 : mNeckoParent(neckoParent)
49 , mIPCOpen(false)
50 {
51   mServerSocket = new TCPServerSocket(nullptr, aLocalPort, aUseArrayBuffers, aBacklog);
52   mServerSocket->SetServerBridgeParent(this);
53 }
54 
~TCPServerSocketParent()55 TCPServerSocketParent::~TCPServerSocketParent()
56 {
57 }
58 
59 void
Init()60 TCPServerSocketParent::Init()
61 {
62   NS_ENSURE_SUCCESS_VOID(mServerSocket->Init());
63 }
64 
65 uint32_t
GetAppId()66 TCPServerSocketParent::GetAppId()
67 {
68   const PContentParent *content = Manager()->Manager();
69   if (PBrowserParent* browser = SingleManagedOrNull(content->ManagedPBrowserParent())) {
70     TabParent *tab = TabParent::GetFrom(browser);
71     return tab->OwnAppId();
72   } else {
73     return nsIScriptSecurityManager::UNKNOWN_APP_ID;
74   }
75 }
76 
77 bool
GetInIsolatedMozBrowser()78 TCPServerSocketParent::GetInIsolatedMozBrowser()
79 {
80   const PContentParent *content = Manager()->Manager();
81   if (PBrowserParent* browser = SingleManagedOrNull(content->ManagedPBrowserParent())) {
82     TabParent *tab = TabParent::GetFrom(browser);
83     return tab->IsIsolatedMozBrowserElement();
84   } else {
85     return false;
86   }
87 }
88 
89 nsresult
SendCallbackAccept(TCPSocketParent * socket)90 TCPServerSocketParent::SendCallbackAccept(TCPSocketParent *socket)
91 {
92   socket->AddIPDLReference();
93 
94   nsresult rv;
95 
96   nsString host;
97   rv = socket->GetHost(host);
98   if (NS_FAILED(rv)) {
99     NS_ERROR("Failed to get host from nsITCPSocketParent");
100     return NS_ERROR_FAILURE;
101   }
102 
103   uint16_t port;
104   rv = socket->GetPort(&port);
105   if (NS_FAILED(rv)) {
106     NS_ERROR("Failed to get port from nsITCPSocketParent");
107     return NS_ERROR_FAILURE;
108   }
109 
110   if (mNeckoParent) {
111     if (mNeckoParent->SendPTCPSocketConstructor(socket, host, port)) {
112       mozilla::Unused << PTCPServerSocketParent::SendCallbackAccept(socket);
113     }
114     else {
115       NS_ERROR("Sending data from PTCPSocketParent was failed.");
116     }
117   }
118   else {
119     NS_ERROR("The member value for NeckoParent is wrong.");
120   }
121   return NS_OK;
122 }
123 
124 bool
RecvClose()125 TCPServerSocketParent::RecvClose()
126 {
127   NS_ENSURE_TRUE(mServerSocket, true);
128   mServerSocket->Close();
129   return true;
130 }
131 
132 void
ActorDestroy(ActorDestroyReason why)133 TCPServerSocketParent::ActorDestroy(ActorDestroyReason why)
134 {
135   if (mServerSocket) {
136     mServerSocket->Close();
137     mServerSocket = nullptr;
138   }
139   mNeckoParent = nullptr;
140 }
141 
142 bool
RecvRequestDelete()143 TCPServerSocketParent::RecvRequestDelete()
144 {
145   mozilla::Unused << Send__delete__(this);
146   return true;
147 }
148 
149 void
OnConnect(TCPServerSocketEvent * event)150 TCPServerSocketParent::OnConnect(TCPServerSocketEvent* event)
151 {
152   RefPtr<TCPSocket> socket = event->Socket();
153   socket->SetAppIdAndBrowser(GetAppId(), GetInIsolatedMozBrowser());
154 
155   RefPtr<TCPSocketParent> socketParent = new TCPSocketParent();
156   socketParent->SetSocket(socket);
157 
158   socket->SetSocketBridgeParent(socketParent);
159 
160   SendCallbackAccept(socketParent);
161 }
162 
163 } // namespace dom
164 } // namespace mozilla
165