/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsIScriptSecurityManager.h" #include "TCPServerSocketParent.h" #include "nsJSUtils.h" #include "TCPSocketParent.h" #include "mozilla/unused.h" #include "mozilla/AppProcessChecker.h" #include "mozilla/dom/ContentParent.h" #include "mozilla/dom/TabParent.h" namespace mozilla { namespace dom { static void FireInteralError(mozilla::net::PTCPServerSocketParent* aActor, uint32_t aLineNo) { mozilla::unused << aActor->SendCallbackError(NS_LITERAL_STRING("Internal error"), NS_LITERAL_STRING(__FILE__), aLineNo, 0); } NS_IMPL_CYCLE_COLLECTION(TCPServerSocketParent, mServerSocket, mIntermediary) NS_IMPL_CYCLE_COLLECTING_ADDREF(TCPServerSocketParent) NS_IMPL_CYCLE_COLLECTING_RELEASE(TCPServerSocketParent) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TCPServerSocketParent) NS_INTERFACE_MAP_ENTRY(nsITCPServerSocketParent) NS_INTERFACE_MAP_ENTRY(nsISupports) NS_INTERFACE_MAP_END void TCPServerSocketParent::ReleaseIPDLReference() { MOZ_ASSERT(mIPCOpen); mIPCOpen = false; this->Release(); } void TCPServerSocketParent::AddIPDLReference() { MOZ_ASSERT(!mIPCOpen); mIPCOpen = true; this->AddRef(); } bool TCPServerSocketParent::Init(PNeckoParent* neckoParent, const uint16_t& aLocalPort, const uint16_t& aBacklog, const nsString& aBinaryType) { mNeckoParent = neckoParent; nsresult rv; mIntermediary = do_CreateInstance("@mozilla.org/tcp-socket-intermediary;1", &rv); if (NS_FAILED(rv)) { FireInteralError(this, __LINE__); return true; } rv = mIntermediary->Listen(this, aLocalPort, aBacklog, aBinaryType, GetAppId(), GetInBrowser(), getter_AddRefs(mServerSocket)); if (NS_FAILED(rv) || !mServerSocket) { FireInteralError(this, __LINE__); return true; } return true; } uint32_t TCPServerSocketParent::GetAppId() { uint32_t appId = nsIScriptSecurityManager::UNKNOWN_APP_ID; const PContentParent *content = Manager()->Manager(); const InfallibleTArray& browsers = content->ManagedPBrowserParent(); if (browsers.Length() > 0) { TabParent *tab = TabParent::GetFrom(browsers[0]); appId = tab->OwnAppId(); } return appId; }; bool TCPServerSocketParent::GetInBrowser() { bool inBrowser = false; const PContentParent *content = Manager()->Manager(); const InfallibleTArray& browsers = content->ManagedPBrowserParent(); if (browsers.Length() > 0) { TabParent *tab = TabParent::GetFrom(browsers[0]); inBrowser = tab->IsBrowserElement(); } return inBrowser; } NS_IMETHODIMP TCPServerSocketParent::SendCallbackAccept(nsITCPSocketParent *socket) { TCPSocketParent* _socket = static_cast(socket); PTCPSocketParent* _psocket = static_cast(_socket); _socket->AddIPDLReference(); nsresult rv; nsString host; rv = socket->GetHost(host); if (NS_FAILED(rv)) { NS_ERROR("Failed to get host from nsITCPSocketParent"); return NS_ERROR_FAILURE; } uint16_t port; rv = socket->GetPort(&port); if (NS_FAILED(rv)) { NS_ERROR("Failed to get port from nsITCPSocketParent"); return NS_ERROR_FAILURE; } if (mNeckoParent) { if (mNeckoParent->SendPTCPSocketConstructor(_psocket, host, port)) { mozilla::unused << PTCPServerSocketParent::SendCallbackAccept(_psocket); } else { NS_ERROR("Sending data from PTCPSocketParent was failed."); }; } else { NS_ERROR("The member value for NeckoParent is wrong."); } return NS_OK; } NS_IMETHODIMP TCPServerSocketParent::SendCallbackError(const nsAString& message, const nsAString& filename, uint32_t lineNumber, uint32_t columnNumber) { mozilla::unused << PTCPServerSocketParent::SendCallbackError(nsString(message), nsString(filename), lineNumber, columnNumber); return NS_OK; } bool TCPServerSocketParent::RecvClose() { NS_ENSURE_TRUE(mServerSocket, true); mServerSocket->Close(); return true; } void TCPServerSocketParent::ActorDestroy(ActorDestroyReason why) { if (mServerSocket) { mServerSocket->Close(); mServerSocket = nullptr; } mNeckoParent = nullptr; mIntermediary = nullptr; } bool TCPServerSocketParent::RecvRequestDelete() { mozilla::unused << Send__delete__(this); return true; } } // namespace dom } // namespace mozilla