diff options
Diffstat (limited to 'ipc')
63 files changed, 5 insertions, 9721 deletions
diff --git a/ipc/app/moz.build b/ipc/app/moz.build index 55c338cb8..3e6461584 100644 --- a/ipc/app/moz.build +++ b/ipc/app/moz.build @@ -43,47 +43,10 @@ if CONFIG['OS_ARCH'] == 'WINNT': 'nss3.dll', ] - if CONFIG['MOZ_SANDBOX']: - # For sandbox includes and the include dependencies those have - LOCAL_INCLUDES += [ - '/security/sandbox/chromium', - '/security/sandbox/chromium-shim', - ] - - USE_LIBS += [ - 'sandbox_s', - ] - - DELAYLOAD_DLLS += [ - 'winmm.dll', - 'user32.dll', - ] - DELAYLOAD_DLLS += [ 'xul.dll', ] -if CONFIG['MOZ_SANDBOX'] and CONFIG['OS_TARGET'] in ('Linux', 'Android'): - USE_LIBS += [ - 'mozsandbox', - ] - - # gcc lto likes to put the top level asm in syscall.cc in a different partition - # from the function using it which breaks the build. Work around that by - # forcing there to be only one partition. - if '-flto' in CONFIG['OS_CXXFLAGS'] and not CONFIG['CLANG_CXX']: - LDFLAGS += ['--param lto-partitions=1'] - -if CONFIG['MOZ_SANDBOX'] and CONFIG['OS_TARGET'] == 'Darwin': - # For sandbox includes and the include dependencies those have - LOCAL_INCLUDES += [ - '/security/sandbox/chromium', - '/security/sandbox/chromium-shim', - ] - USE_LIBS += [ - 'mozsandbox', - ] - if CONFIG['_MSC_VER']: # Always enter a Windows program through wmain, whether or not we're # a console application. @@ -102,12 +65,6 @@ LDFLAGS += CONFIG['MOZ_ALLOW_HEAP_EXECUTE_FLAGS'] if CONFIG['OS_ARCH'] == 'WINNT' and not CONFIG['GNU_CC']: LDFLAGS += ['/HEAP:0x40000'] -if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': - OS_LIBS += [ - 'binder', - 'utils', - ] - if CONFIG['GNU_CXX']: CXXFLAGS += ['-Wshadow'] diff --git a/ipc/app/pie/moz.build b/ipc/app/pie/moz.build index 0247b25b4..6924199b5 100644 --- a/ipc/app/pie/moz.build +++ b/ipc/app/pie/moz.build @@ -16,15 +16,4 @@ LOCAL_INCLUDES += [ '/xpcom/base', ] -if CONFIG['MOZ_SANDBOX']: - USE_LIBS += [ - 'mozsandbox', - ] - - # gcc lto likes to put the top level asm in syscall.cc in a different partition - # from the function using it which breaks the build. Work around that by - # forcing there to be only one partition. - if '-flto' in CONFIG['OS_CXXFLAGS'] and not CONFIG['CLANG_CXX']: - LDFLAGS += ['--param lto-partitions=1'] - LDFLAGS += ['-pie'] diff --git a/ipc/chromium/moz.build b/ipc/chromium/moz.build index aad46b59e..f047e7011 100644 --- a/ipc/chromium/moz.build +++ b/ipc/chromium/moz.build @@ -131,8 +131,6 @@ if os_linux: ] DEFINES['ANDROID'] = True DEFINES['_POSIX_MONOTONIC_CLOCK'] = 0 - if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': - DEFINES['HAVE_ANDROID_OS'] = True if os_bsd or os_linux: if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']: diff --git a/ipc/chromium/src/base/platform_thread_posix.cc b/ipc/chromium/src/base/platform_thread_posix.cc index 6c978336e..4acd95f23 100644 --- a/ipc/chromium/src/base/platform_thread_posix.cc +++ b/ipc/chromium/src/base/platform_thread_posix.cc @@ -48,11 +48,7 @@ PlatformThreadId PlatformThread::CurrentId() { mach_port_deallocate(mach_task_self(), port); return port; #elif defined(OS_LINUX) -#ifdef MOZ_WIDGET_GONK - return (intptr_t) (pthread_self()); -#else return syscall(__NR_gettid); -#endif #elif defined(OS_OPENBSD) || defined(__GLIBC__) return (intptr_t) (pthread_self()); #elif defined(OS_NETBSD) diff --git a/ipc/chromium/src/base/process_util_linux.cc b/ipc/chromium/src/base/process_util_linux.cc index 204017db5..57388ccb0 100644 --- a/ipc/chromium/src/base/process_util_linux.cc +++ b/ipc/chromium/src/base/process_util_linux.cc @@ -24,24 +24,13 @@ #include "prenv.h" #include "prmem.h" -#ifdef MOZ_WIDGET_GONK /* - * AID_APP is the first application UID used by Android. We're using - * it as our unprivilegied UID. This ensure the UID used is not - * shared with any other processes than our own childs. - */ -# include <private/android_filesystem_config.h> -# define CHILD_UNPRIVILEGED_UID AID_APP -# define CHILD_UNPRIVILEGED_GID AID_APP -#else -/* - * On platforms that are not gonk based, we fall back to an arbitrary - * UID. This is generally the UID for user `nobody', albeit it is not + * On our platforms we use an arbitrary UID. + * This is generally the UID for user `nobody', albeit it is not * always the case. */ # define CHILD_UNPRIVILEGED_UID 65534 # define CHILD_UNPRIVILEGED_GID 65534 -#endif namespace { @@ -229,36 +218,6 @@ void SetCurrentProcessPrivileges(ChildPrivileges privs) { gid_t gid = CHILD_UNPRIVILEGED_GID; uid_t uid = CHILD_UNPRIVILEGED_UID; -#ifdef MOZ_WIDGET_GONK - { - static bool checked_pix_max, pix_max_ok; - if (!checked_pix_max) { - checked_pix_max = true; - int fd = open("/proc/sys/kernel/pid_max", O_CLOEXEC | O_RDONLY); - if (fd < 0) { - DLOG(ERROR) << "Failed to open pid_max"; - _exit(127); - } - char buf[PATH_MAX]; - ssize_t len = read(fd, buf, sizeof(buf) - 1); - close(fd); - if (len < 0) { - DLOG(ERROR) << "Failed to read pid_max"; - _exit(127); - } - buf[len] = '\0'; - int pid_max = atoi(buf); - pix_max_ok = - (pid_max + CHILD_UNPRIVILEGED_UID > CHILD_UNPRIVILEGED_UID); - } - if (!pix_max_ok) { - DLOG(ERROR) << "Can't safely get unique uid/gid"; - _exit(127); - } - gid += getpid(); - uid += getpid(); - } -#endif if (setgid(gid) != 0) { DLOG(ERROR) << "FAILED TO setgid() CHILD PROCESS"; _exit(127); diff --git a/ipc/contentproc/moz.build b/ipc/contentproc/moz.build index 07cf0b97c..f9ded56ec 100644 --- a/ipc/contentproc/moz.build +++ b/ipc/contentproc/moz.build @@ -18,8 +18,3 @@ if CONFIG['OS_ARCH'] == 'WINNT': '/xpcom/base', ] -if CONFIG['MOZ_SANDBOX'] and CONFIG['OS_ARCH'] == 'WINNT': - LOCAL_INCLUDES += [ - '/security/sandbox/chromium', - '/security/sandbox/chromium-shim', - ] diff --git a/ipc/contentproc/plugin-container.cpp b/ipc/contentproc/plugin-container.cpp index f293889b0..2fb9bd4f5 100644 --- a/ipc/contentproc/plugin-container.cpp +++ b/ipc/contentproc/plugin-container.cpp @@ -22,118 +22,10 @@ #include "GMPLoader.h" -#if defined(XP_WIN) && defined(MOZ_SANDBOX) -#include "mozilla/sandboxing/SandboxInitialization.h" -#include "mozilla/sandboxing/sandboxLogging.h" -#endif - -#if defined(XP_LINUX) && defined(MOZ_GMP_SANDBOX) -#include "mozilla/Sandbox.h" -#include "mozilla/SandboxInfo.h" -#endif - -#ifdef MOZ_WIDGET_GONK -# include <sys/time.h> -# include <sys/resource.h> - -# include <binder/ProcessState.h> - -# ifdef LOGE_IF -# undef LOGE_IF -# endif - -# include <android/log.h> -# define LOGE_IF(cond, ...) \ - ( (CONDITION(cond)) \ - ? ((void)__android_log_print(ANDROID_LOG_ERROR, \ - "Gecko:MozillaRntimeMain", __VA_ARGS__)) \ - : (void)0 ) - -# ifdef MOZ_CONTENT_SANDBOX -# include "mozilla/Sandbox.h" -# endif - -#endif // MOZ_WIDGET_GONK - -#ifdef MOZ_WIDGET_GONK -static void -InitializeBinder(void *aDummy) { - // Change thread priority to 0 only during calling ProcessState::self(). - // The priority is registered to binder driver and used for default Binder - // Thread's priority. - // To change the process's priority to small value need's root permission. - int curPrio = getpriority(PRIO_PROCESS, 0); - int err = setpriority(PRIO_PROCESS, 0, 0); - MOZ_ASSERT(!err); - LOGE_IF(err, "setpriority failed. Current process needs root permission."); - android::ProcessState::self()->startThreadPool(); - setpriority(PRIO_PROCESS, 0, curPrio); -} -#endif - -#if defined(XP_WIN) && defined(MOZ_SANDBOX) -class WinSandboxStarter : public mozilla::gmp::SandboxStarter { -public: - virtual bool Start(const char *aLibPath) override { - if (IsSandboxedProcess()) { - mozilla::sandboxing::LowerSandbox(); - } - return true; - } -}; -#endif - -#if defined(XP_LINUX) && defined(MOZ_GMP_SANDBOX) -class LinuxSandboxStarter : public mozilla::gmp::SandboxStarter { - LinuxSandboxStarter() { } -public: - static SandboxStarter* Make() { - if (mozilla::SandboxInfo::Get().CanSandboxMedia()) { - return new LinuxSandboxStarter(); - } else { - // Sandboxing isn't possible, but the parent has already - // checked that this plugin doesn't require it. (Bug 1074561) - return nullptr; - } - } - virtual bool Start(const char *aLibPath) override { - mozilla::SetMediaPluginSandbox(aLibPath); - return true; - } -}; -#endif - -#if defined(XP_MACOSX) && defined(MOZ_GMP_SANDBOX) -class MacSandboxStarter : public mozilla::gmp::SandboxStarter { -public: - virtual bool Start(const char *aLibPath) override { - std::string err; - bool rv = mozilla::StartMacSandbox(mInfo, err); - if (!rv) { - fprintf(stderr, "sandbox_init() failed! Error \"%s\"\n", err.c_str()); - } - return rv; - } - virtual void SetSandboxInfo(MacSandboxInfo* aSandboxInfo) override { - mInfo = *aSandboxInfo; - } -private: - MacSandboxInfo mInfo; -}; -#endif - mozilla::gmp::SandboxStarter* MakeSandboxStarter() { -#if defined(XP_WIN) && defined(MOZ_SANDBOX) - return new WinSandboxStarter(); -#elif defined(XP_LINUX) && defined(MOZ_GMP_SANDBOX) - return LinuxSandboxStarter::Make(); -#elif defined(XP_MACOSX) && defined(MOZ_GMP_SANDBOX) - return new MacSandboxStarter(); -#else return nullptr; -#endif } int @@ -147,36 +39,8 @@ content_process_main(int argc, char* argv[]) XREChildData childData; -#if defined(XP_WIN) && defined(MOZ_SANDBOX) - if (IsSandboxedProcess()) { - childData.sandboxTargetServices = - mozilla::sandboxing::GetInitializedTargetServices(); - if (!childData.sandboxTargetServices) { - return 1; - } - - childData.ProvideLogFunction = mozilla::sandboxing::ProvideLogFunction; - } -#endif - XRE_SetProcessType(argv[--argc]); -#if defined(XP_LINUX) && defined(MOZ_SANDBOX) - // This has to happen while we're still single-threaded, and on - // B2G that means before the Android Binder library is - // initialized. - mozilla::SandboxEarlyInit(XRE_GetProcessType()); -#endif - -#ifdef MOZ_WIDGET_GONK - // This creates a ThreadPool for binder ipc. A ThreadPool is necessary to - // receive binder calls, though not necessary to send binder calls. - // ProcessState::Self() also needs to be called once on the main thread to - // register the main thread with the binder driver. - - InitializeBinder(nullptr); -#endif - #ifdef XP_WIN // For plugins, this is done in PluginProcessChild::Init, as we need to // avoid it for unsupported plugins. See PluginProcessChild::Init for @@ -186,7 +50,7 @@ content_process_main(int argc, char* argv[]) SetDllDirectoryW(L""); } #endif -#if !defined(MOZ_WIDGET_ANDROID) && !defined(MOZ_WIDGET_GONK) && defined(MOZ_PLUGIN_CONTAINER) +#if !defined(MOZ_WIDGET_ANDROID) && defined(MOZ_PLUGIN_CONTAINER) // On desktop, the GMPLoader lives in plugin-container, so that its // code can be covered by an EME/GMP vendor's voucher. nsAutoPtr<mozilla::gmp::SandboxStarter> starter(MakeSandboxStarter()); diff --git a/ipc/dbus/DBusHelpers.cpp b/ipc/dbus/DBusHelpers.cpp index 73b4596f2..f5c684572 100644 --- a/ipc/dbus/DBusHelpers.cpp +++ b/ipc/dbus/DBusHelpers.cpp @@ -14,12 +14,7 @@ #include "nsThreadUtils.h" #undef CHROMIUM_LOG -#if defined(MOZ_WIDGET_GONK) -#include <android/log.h> -#define CHROMIUM_LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gonk", args); -#else #define CHROMIUM_LOG(args...) printf(args); -#endif namespace mozilla { namespace ipc { diff --git a/ipc/dbus/DBusUtils.cpp b/ipc/dbus/DBusUtils.cpp index 6e36bca0f..7bcf749f8 100644 --- a/ipc/dbus/DBusUtils.cpp +++ b/ipc/dbus/DBusUtils.cpp @@ -20,12 +20,7 @@ #include "DBusUtils.h" #undef CHROMIUM_LOG -#if defined(MOZ_WIDGET_GONK) -#include <android/log.h> -#define CHROMIUM_LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gonk", args); -#else #define CHROMIUM_LOG(args...) printf(args); -#endif namespace mozilla { namespace ipc { diff --git a/ipc/glue/GeckoChildProcessHost.cpp b/ipc/glue/GeckoChildProcessHost.cpp index db8ab3d0a..e58408e0c 100644 --- a/ipc/glue/GeckoChildProcessHost.cpp +++ b/ipc/glue/GeckoChildProcessHost.cpp @@ -23,10 +23,6 @@ #include "prenv.h" #include "nsXPCOMPrivate.h" -#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX) -#include "nsAppDirectoryServiceDefs.h" -#endif - #include "nsExceptionHandler.h" #include "nsDirectoryServiceDefs.h" @@ -43,12 +39,6 @@ #ifdef XP_WIN #include "nsIWinTaskbar.h" #define NS_TASKBAR_CONTRACTID "@mozilla.org/windows-taskbar;1" - -#if defined(MOZ_SANDBOX) -#include "mozilla/Preferences.h" -#include "mozilla/sandboxing/sandboxLogging.h" -#include "nsDirectoryServiceUtils.h" -#endif #endif #include "nsTArray.h" @@ -72,13 +62,9 @@ static const int kMagicAndroidSystemPropFd = 5; #endif static const bool kLowRightsSubprocesses = - // We currently only attempt to drop privileges on gonk, because we - // have no plugins or extensions to worry about breaking. -#ifdef MOZ_WIDGET_GONK - true -#else + // We only attempted to drop privileges on gonk, because it + // had no plugins or extensions to worry about breaking. false -#endif ; static bool @@ -101,10 +87,6 @@ GeckoChildProcessHost::GeckoChildProcessHost(GeckoProcessType aProcessType, mPrivileges(aPrivileges), mMonitor("mozilla.ipc.GeckChildProcessHost.mMonitor"), mProcessState(CREATING_CHANNEL), -#if defined(MOZ_SANDBOX) && defined(XP_WIN) - mEnableSandboxLogging(false), - mSandboxLevel(0), -#endif mChildProcessHandle(0) #if defined(MOZ_WIDGET_COCOA) , mChildTask(MACH_PORT_NULL) @@ -311,23 +293,6 @@ GeckoChildProcessHost::PrepareLaunch() if (mProcessType == GeckoProcessType_Plugin) { InitWindowsGroupID(); } - -#if defined(MOZ_CONTENT_SANDBOX) - // We need to get the pref here as the process is launched off main thread. - if (mProcessType == GeckoProcessType_Content) { - mSandboxLevel = Preferences::GetInt("security.sandbox.content.level"); - mEnableSandboxLogging = - Preferences::GetBool("security.sandbox.windows.log"); - } -#endif - -#if defined(MOZ_SANDBOX) - // For other process types we can't rely on them being launched on main - // thread and they may not have access to prefs in the child process, so allow - // them to turn on logging via an environment variable. - mEnableSandboxLogging = mEnableSandboxLogging - || !!PR_GetEnv("MOZ_WIN_SANDBOX_LOGGING"); -#endif #endif } @@ -608,109 +573,10 @@ AddAppDirToCommandLine(std::vector<std::string>& aCmdLine) aCmdLine.push_back(path.get()); #endif } - -#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX) - // Full path to the profile dir - nsCOMPtr<nsIFile> profileDir; - rv = directoryService->Get(NS_APP_USER_PROFILE_50_DIR, - NS_GET_IID(nsIFile), - getter_AddRefs(profileDir)); - if (NS_SUCCEEDED(rv)) { - nsAutoCString path; - MOZ_ALWAYS_SUCCEEDS(profileDir->GetNativePath(path)); - aCmdLine.push_back("-profile"); - aCmdLine.push_back(path.get()); - } -#endif - } - } -} - -#if defined(XP_WIN) && defined(MOZ_SANDBOX) -static void -MaybeAddNsprLogFileAccess(std::vector<std::wstring>& aAllowedFilesReadWrite) -{ - const char* nsprLogFileEnv = PR_GetEnv("NSPR_LOG_FILE"); - if (!nsprLogFileEnv) { - return; - } - - nsDependentCString nsprLogFilePath(nsprLogFileEnv); - nsCOMPtr<nsIFile> nsprLogFile; - nsresult rv = NS_NewNativeLocalFile(nsprLogFilePath, true, - getter_AddRefs(nsprLogFile)); - if (NS_FAILED(rv)) { - // Not an absolute path, try it as a relative one. - nsresult rv = NS_GetSpecialDirectory(NS_OS_CURRENT_WORKING_DIR, - getter_AddRefs(nsprLogFile)); - if (NS_FAILED(rv) || !nsprLogFile) { - NS_WARNING("Failed to get current working directory"); - return; - } - - rv = nsprLogFile->AppendRelativeNativePath(nsprLogFilePath); - if (NS_WARN_IF(NS_FAILED(rv))) { - return; } } - - nsAutoString resolvedFilePath; - rv = nsprLogFile->GetPath(resolvedFilePath); - if (NS_WARN_IF(NS_FAILED(rv))) { - return; - } - - // Update the environment variable as well as adding the rule, because the - // Chromium sandbox can only allow access to fully qualified file paths. This - // only affects the environment for the child process we're about to create, - // because this will get reset to the original value in PerformAsyncLaunch. - aAllowedFilesReadWrite.push_back(std::wstring(resolvedFilePath.get())); - nsAutoCString resolvedEnvVar("NSPR_LOG_FILE="); - AppendUTF16toUTF8(resolvedFilePath, resolvedEnvVar); - PR_SetEnv(resolvedEnvVar.get()); } -static void -AddContentSandboxAllowedFiles(int32_t aSandboxLevel, - std::vector<std::wstring>& aAllowedFilesRead) -{ - if (aSandboxLevel < 1) { - return; - } - - nsCOMPtr<nsIFile> binDir; - nsresult rv = NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(binDir)); - if (NS_WARN_IF(NS_FAILED(rv))) { - return; - } - - nsAutoString binDirPath; - rv = binDir->GetPath(binDirPath); - if (NS_WARN_IF(NS_FAILED(rv))) { - return; - } - - // If bin directory is on a remote drive add read access. - wchar_t volPath[MAX_PATH]; - if (!::GetVolumePathNameW(binDirPath.get(), volPath, MAX_PATH)) { - return; - } - - if (::GetDriveTypeW(volPath) != DRIVE_REMOTE) { - return; - } - - // Convert network share path to format for sandbox policy. - if (Substring(binDirPath, 0, 2).Equals(L"\\\\")) { - binDirPath.InsertLiteral(u"??\\UNC", 1); - } - - binDirPath.AppendLiteral(u"\\*"); - - aAllowedFilesRead.push_back(std::wstring(binDirPath.get())); -} -#endif - bool GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExtraOpts, base::ProcessArchitecture arch) { @@ -829,33 +695,6 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt } #endif // ANDROID -#ifdef MOZ_WIDGET_GONK - if (const char *ldPreloadPath = getenv("LD_PRELOAD")) { - newEnvVars["LD_PRELOAD"] = ldPreloadPath; - } -#endif // MOZ_WIDGET_GONK - -#if defined(XP_LINUX) && defined(MOZ_SANDBOX) - // Preload libmozsandbox.so so that sandbox-related interpositions - // can be defined there instead of in the executable. - // (This could be made conditional on intent to use sandboxing, but - // it's harmless for non-sandboxed processes.) - { - nsAutoCString preload; - // Prepend this, because people can and do preload libpthread. - // (See bug 1222500.) - preload.AssignLiteral("libmozsandbox.so"); - if (const char* oldPreload = PR_GetEnv("LD_PRELOAD")) { - // Doesn't matter if oldPreload is ""; extra separators are ignored. - preload.Append(' '); - preload.Append(oldPreload); - } - // Explicitly construct the std::string to make it clear that this - // isn't retaining a pointer to the nsCString's buffer. - newEnvVars["LD_PRELOAD"] = std::string(preload.get()); - } -#endif - // remap the IPC socket fd to a well-known int, as the OS does for // STDOUT_FILENO, for example int srcChannelFd, dstChannelFd; @@ -1021,85 +860,6 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt } } -#if defined(XP_WIN) && defined(MOZ_SANDBOX) - bool shouldSandboxCurrentProcess = false; - - // XXX: Bug 1124167: We should get rid of the process specific logic for - // sandboxing in this class at some point. Unfortunately it will take a bit - // of reorganizing so I don't think this patch is the right time. - switch (mProcessType) { - case GeckoProcessType_Content: -#if defined(MOZ_CONTENT_SANDBOX) - if (mSandboxLevel > 0 && - !PR_GetEnv("MOZ_DISABLE_CONTENT_SANDBOX")) { - // For now we treat every failure as fatal in SetSecurityLevelForContentProcess - // and just crash there right away. Should this change in the future then we - // should also handle the error here. - mSandboxBroker.SetSecurityLevelForContentProcess(mSandboxLevel); - shouldSandboxCurrentProcess = true; - AddContentSandboxAllowedFiles(mSandboxLevel, mAllowedFilesRead); - } -#endif // MOZ_CONTENT_SANDBOX - break; - case GeckoProcessType_Plugin: - if (mSandboxLevel > 0 && - !PR_GetEnv("MOZ_DISABLE_NPAPI_SANDBOX")) { - bool ok = mSandboxBroker.SetSecurityLevelForPluginProcess(mSandboxLevel); - if (!ok) { - return false; - } - shouldSandboxCurrentProcess = true; - } - break; - case GeckoProcessType_IPDLUnitTest: - // XXX: We don't sandbox this process type yet - break; - case GeckoProcessType_GMPlugin: - if (!PR_GetEnv("MOZ_DISABLE_GMP_SANDBOX")) { - // The Widevine CDM on Windows can only load at USER_RESTRICTED, - // not at USER_LOCKDOWN. So look in the command line arguments - // to see if we're loading the path to the Widevine CDM, and if - // so use sandbox level USER_RESTRICTED instead of USER_LOCKDOWN. - bool isWidevine = std::any_of(aExtraOpts.begin(), aExtraOpts.end(), - [](const std::string arg) { return arg.find("gmp-widevinecdm") != std::string::npos; }); - auto level = isWidevine ? SandboxBroker::Restricted : SandboxBroker::LockDown; - bool ok = mSandboxBroker.SetSecurityLevelForGMPlugin(level); - if (!ok) { - return false; - } - shouldSandboxCurrentProcess = true; - } - break; - case GeckoProcessType_GPU: - break; - case GeckoProcessType_Default: - default: - MOZ_CRASH("Bad process type in GeckoChildProcessHost"); - break; - }; - - if (shouldSandboxCurrentProcess) { - MaybeAddNsprLogFileAccess(mAllowedFilesReadWrite); - for (auto it = mAllowedFilesRead.begin(); - it != mAllowedFilesRead.end(); - ++it) { - mSandboxBroker.AllowReadFile(it->c_str()); - } - - for (auto it = mAllowedFilesReadWrite.begin(); - it != mAllowedFilesReadWrite.end(); - ++it) { - mSandboxBroker.AllowReadWriteFile(it->c_str()); - } - - for (auto it = mAllowedDirectories.begin(); - it != mAllowedDirectories.end(); - ++it) { - mSandboxBroker.AllowDirectory(it->c_str()); - } - } -#endif // XP_WIN && MOZ_SANDBOX - // Add the application directory path (-appdir path) AddAppDirToCommandLine(cmdLine); @@ -1116,33 +876,8 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt // Process type cmdLine.AppendLooseValue(UTF8ToWide(childProcessType)); -#if defined(XP_WIN) && defined(MOZ_SANDBOX) - if (shouldSandboxCurrentProcess) { - if (mSandboxBroker.LaunchApp(cmdLine.program().c_str(), - cmdLine.command_line_string().c_str(), - mEnableSandboxLogging, - &process)) { - EnvironmentLog("MOZ_PROCESS_LOG").print( - "==> process %d launched child process %d (%S)\n", - base::GetCurrentProcId(), base::GetProcId(process), - cmdLine.command_line_string().c_str()); - } - } else -#endif { base::LaunchApp(cmdLine, false, false, &process); - -#ifdef MOZ_SANDBOX - // We need to be able to duplicate handles to some types of non-sandboxed - // child processes. - if (mProcessType == GeckoProcessType_Content || - mProcessType == GeckoProcessType_GPU || - mProcessType == GeckoProcessType_GMPlugin) { - if (!mSandboxBroker.AddTargetPeer(process)) { - NS_WARNING("Failed to add content process as target peer."); - } - } -#endif } #else diff --git a/ipc/glue/GeckoChildProcessHost.h b/ipc/glue/GeckoChildProcessHost.h index 3d55564ac..d278d8928 100644 --- a/ipc/glue/GeckoChildProcessHost.h +++ b/ipc/glue/GeckoChildProcessHost.h @@ -21,10 +21,6 @@ #include "nsXULAppAPI.h" // for GeckoProcessType #include "nsString.h" -#if defined(XP_WIN) && defined(MOZ_SANDBOX) -#include "sandboxBroker.h" -#endif - namespace mozilla { namespace ipc { @@ -153,15 +149,6 @@ protected: #ifdef XP_WIN void InitWindowsGroupID(); nsString mGroupId; - -#ifdef MOZ_SANDBOX - SandboxBroker mSandboxBroker; - std::vector<std::wstring> mAllowedFilesRead; - std::vector<std::wstring> mAllowedFilesReadWrite; - std::vector<std::wstring> mAllowedDirectories; - bool mEnableSandboxLogging; - int32_t mSandboxLevel; -#endif #endif // XP_WIN #if defined(OS_POSIX) diff --git a/ipc/glue/MessageChannel.cpp b/ipc/glue/MessageChannel.cpp index 70e2387d5..7861f3e2d 100644 --- a/ipc/glue/MessageChannel.cpp +++ b/ipc/glue/MessageChannel.cpp @@ -27,13 +27,8 @@ using mozilla::Move; // Undo the damage done by mozzconf.h #undef compress -// Logging seems to be somewhat broken on b2g. -#ifdef MOZ_B2G -#define IPC_LOG(...) -#else static mozilla::LazyLogModule sLogModule("ipc"); #define IPC_LOG(...) MOZ_LOG(sLogModule, LogLevel::Debug, (__VA_ARGS__)) -#endif /* * IPC design: diff --git a/ipc/glue/ProtocolUtils.cpp b/ipc/glue/ProtocolUtils.cpp index 4de131469..7d8a1153c 100644 --- a/ipc/glue/ProtocolUtils.cpp +++ b/ipc/glue/ProtocolUtils.cpp @@ -20,11 +20,6 @@ #include "mozilla/Unused.h" #include "nsPrintfCString.h" -#if defined(MOZ_SANDBOX) && defined(XP_WIN) -#define TARGET_SANDBOX_EXPORTS -#include "mozilla/sandboxTarget.h" -#endif - #include "nsAutoPtr.h" using namespace IPC; @@ -162,17 +157,6 @@ bool DuplicateHandle(HANDLE aSourceHandle, } -#if defined(MOZ_SANDBOX) - // Try the broker next (will fail if not sandboxed). - if (SandboxTarget::Instance()->BrokerDuplicateHandle(aSourceHandle, - aTargetProcessId, - aTargetHandle, - aDesiredAccess, - aOptions)) { - return true; - } -#endif - // Finally, see if we already have access to the process. ScopedProcessHandle targetProcess(OpenProcess(PROCESS_DUP_HANDLE, FALSE, diff --git a/ipc/glue/moz.build b/ipc/glue/moz.build index dd3a2e1ba..8caee1ffe 100644 --- a/ipc/glue/moz.build +++ b/ipc/glue/moz.build @@ -196,12 +196,5 @@ for var in ('MOZ_CHILD_PROCESS_NAME', 'MOZ_CHILD_PROCESS_NAME_PIE', 'MOZ_CHILD_PROCESS_BUNDLE', 'DLL_PREFIX', 'DLL_SUFFIX'): DEFINES[var] = '"%s"' % CONFIG[var] -if CONFIG['MOZ_SANDBOX'] and CONFIG['OS_ARCH'] == 'WINNT': - LOCAL_INCLUDES += [ - '/security/sandbox/chromium', - '/security/sandbox/chromium-shim', - '/security/sandbox/win/src/sandboxbroker', - ] - if CONFIG['GNU_CXX']: CXXFLAGS += ['-Wno-shadow'] diff --git a/ipc/hal/DaemonRunnables.h b/ipc/hal/DaemonRunnables.h deleted file mode 100644 index e4a528a9b..000000000 --- a/ipc/hal/DaemonRunnables.h +++ /dev/null @@ -1,950 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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/. */ - -#ifndef mozilla_ipc_DaemonRunnables_h -#define mozilla_ipc_DaemonRunnables_h - -#include "mozilla/Unused.h" -#include "mozilla/UniquePtr.h" -#include "nsThreadUtils.h" - -namespace mozilla { -namespace ipc { - -namespace details { - -class DaemonRunnable : public Runnable -{ -protected: - DaemonRunnable() = default; - virtual ~DaemonRunnable() = default; - - template<typename Out, typename In> - static Out& ConvertArg(In& aArg) - { - return aArg; - } - - template<typename Out, typename In> - static Out ConvertArg(UniquePtr<In>& aArg) - { - return aArg.get(); - } -}; - -} // namespace detail - -// -// Result handling -// -// The classes of type |DaemonResultRunnable[0..3]| transfer a result -// handler from the I/O thread to the main thread for execution. Call -// the methods |Create| and |Dispatch| to create or create-and-dispatch -// a result runnable. -// -// You need to specify the called method. The |Create| and |Dispatch| -// methods of |DaemonResultRunnable[1..3]| receive an extra argument -// for initializing the result's arguments. During creation, the result -// runnable calls the supplied class's call operator with the result's -// argument. This is where initialization and conversion from backend- -// specific types is performed. -// - -template <typename Obj, typename Res> -class DaemonResultRunnable0 final : public details::DaemonRunnable -{ -public: - typedef DaemonResultRunnable0<Obj, Res> SelfType; - - template <typename InitOp> - static already_AddRefed<SelfType> - Create(Obj* aObj, Res (Obj::*aMethod)(), const InitOp& aInitOp) - { - RefPtr<SelfType> runnable(new SelfType(aObj, aMethod)); - if (NS_FAILED(runnable->Init(aInitOp))) { - return nullptr; - } - return runnable.forget(); - } - - template <typename InitOp> - static void - Dispatch(Obj* aObj, Res (Obj::*aMethod)(), const InitOp& aInitOp) - { - if (!aObj) { - return; // silently return if no result runnable has been given - } - RefPtr<SelfType> runnable = Create(aObj, aMethod, aInitOp); - if (!runnable) { - return; - } - Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable))); - } - - NS_IMETHOD Run() override - { - ((*mObj).*mMethod)(); - return NS_OK; - } - -private: - DaemonResultRunnable0(Obj* aObj, Res (Obj::*aMethod)()) - : mObj(aObj) - , mMethod(aMethod) - { - MOZ_ASSERT(mObj); - MOZ_ASSERT(mMethod); - } - - template<typename InitOp> - nsresult Init(const InitOp& aInitOp) - { - return aInitOp(); - } - - RefPtr<Obj> mObj; - void (Obj::*mMethod)(); -}; - -template <typename Obj, typename Res, typename Tin1, typename Arg1> -class DaemonResultRunnable1 final : public details::DaemonRunnable -{ -public: - typedef DaemonResultRunnable1<Obj, Res, Tin1, Arg1> SelfType; - - template <typename InitOp> - static already_AddRefed<SelfType> - Create(Obj* aObj, Res (Obj::*aMethod)(Arg1), const InitOp& aInitOp) - { - RefPtr<SelfType> runnable(new SelfType(aObj, aMethod)); - if (NS_FAILED(runnable->Init(aInitOp))) { - return nullptr; - } - return runnable.forget(); - } - - template <typename InitOp> - static void - Dispatch(Obj* aObj, Res (Obj::*aMethod)(Arg1), const InitOp& aInitOp) - { - if (!aObj) { - return; // silently return if no result runnable has been given - } - RefPtr<SelfType> runnable = Create(aObj, aMethod, aInitOp); - if (!runnable) { - return; - } - Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable))); - } - - NS_IMETHOD Run() override - { - ((*mObj).*mMethod)(ConvertArg<Arg1>(mArg1)); - return NS_OK; - } - -private: - DaemonResultRunnable1(Obj* aObj, Res (Obj::*aMethod)(Arg1)) - : mObj(aObj) - , mMethod(aMethod) - { - MOZ_ASSERT(mObj); - MOZ_ASSERT(mMethod); - } - - template<typename InitOp> - nsresult Init(const InitOp& aInitOp) - { - return aInitOp(mArg1); - } - - RefPtr<Obj> mObj; - Res (Obj::*mMethod)(Arg1); - Tin1 mArg1; -}; - -template <typename Obj, typename Res, - typename Tin1, typename Tin2, typename Tin3, - typename Arg1, typename Arg2, typename Arg3> -class DaemonResultRunnable3 final : public details::DaemonRunnable -{ -public: - typedef DaemonResultRunnable3<Obj, Res, - Tin1, Tin2, Tin3, - Arg1, Arg2, Arg3> SelfType; - - template<typename InitOp> - static already_AddRefed<SelfType> - Create(Obj* aObj, Res (Obj::*aMethod)(Arg1, Arg2, Arg3), - const InitOp& aInitOp) - { - RefPtr<SelfType> runnable(new SelfType(aObj, aMethod)); - if (NS_FAILED(runnable->Init(aInitOp))) { - return nullptr; - } - return runnable.forget(); - } - - template<typename InitOp> - static void - Dispatch(Obj* aObj, Res (Obj::*aMethod)(Arg1, Arg2, Arg3), - const InitOp& aInitOp) - { - if (!aObj) { - return; // silently return if no result runnable has been given - } - RefPtr<SelfType> runnable = Create(aObj, aMethod, aInitOp); - if (!runnable) { - return; - } - Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable))); - } - - NS_IMETHOD Run() override - { - ((*mObj).*mMethod)(ConvertArg<Arg1>(mArg1), - ConvertArg<Arg2>(mArg2), - ConvertArg<Arg3>(mArg3)); - return NS_OK; - } - -private: - DaemonResultRunnable3(Obj* aObj, Res (Obj::*aMethod)(Arg1, Arg2, Arg3)) - : mObj(aObj) - , mMethod(aMethod) - { - MOZ_ASSERT(mObj); - MOZ_ASSERT(mMethod); - } - - template<typename InitOp> - nsresult - Init(const InitOp& aInitOp) - { - return aInitOp(mArg1, mArg2, mArg3); - } - - RefPtr<Obj> mObj; - Res (Obj::*mMethod)(Arg1, Arg2, Arg3); - Tin1 mArg1; - Tin2 mArg2; - Tin3 mArg3; -}; - -// -// Notification handling -// -// The classes of type |DaemonNotificationRunnable[0..9]| transfer a -// notification from the I/O thread to a notification handler on the -// main thread. Call the methods |Create| and |Dispatch| to create or -// create-and-dispatch a notification runnable. -// -// Like with result runnables, you need to specify the called method. -// And like with result runnables, the |Create| and |Dispatch| methods -// of |DaemonNotificationRunnable[1..9]| receive an extra argument -// for initializing the notification's arguments. During creation, the -// notification runnable calls the class's call operator with the -// notification's argument. This is where initialization and conversion -// from backend-specific types is performed. -// - -template <typename ObjectWrapper, typename Res> -class DaemonNotificationRunnable0 final : public details::DaemonRunnable -{ -public: - typedef typename ObjectWrapper::ObjectType ObjectType; - typedef DaemonNotificationRunnable0<ObjectWrapper, Res> SelfType; - - template<typename InitOp> - static already_AddRefed<SelfType> - Create(Res (ObjectType::*aMethod)(), const InitOp& aInitOp) - { - RefPtr<SelfType> runnable(new SelfType(aMethod)); - if (NS_FAILED(runnable->Init(aInitOp))) { - return nullptr; - } - return runnable.forget(); - } - - template<typename InitOp> - static void - Dispatch(Res (ObjectType::*aMethod)(), const InitOp& aInitOp) - { - RefPtr<SelfType> runnable = Create(aMethod, aInitOp); - if (!runnable) { - return; - } - Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable))); - } - - NS_IMETHOD Run() override - { - MOZ_ASSERT(NS_IsMainThread()); - - ObjectType* obj = ObjectWrapper::GetInstance(); - if (!obj) { - NS_WARNING("Notification handler not initialized"); - } else { - ((*obj).*mMethod)(); - } - return NS_OK; - } - -private: - DaemonNotificationRunnable0(Res (ObjectType::*aMethod)()) - : mMethod(aMethod) - { - MOZ_ASSERT(mMethod); - } - - template<typename InitOp> - nsresult Init(const InitOp& aInitOp) - { - return aInitOp(); - } - - Res (ObjectType::*mMethod)(); -}; - -template <typename ObjectWrapper, typename Res, - typename Tin1, typename Arg1=Tin1> -class DaemonNotificationRunnable1 final : public details::DaemonRunnable -{ -public: - typedef typename ObjectWrapper::ObjectType ObjectType; - typedef DaemonNotificationRunnable1<ObjectWrapper, Res, - Tin1, Arg1> SelfType; - - template <typename InitOp> - static already_AddRefed<SelfType> - Create(Res (ObjectType::*aMethod)(Arg1), const InitOp& aInitOp) - { - RefPtr<SelfType> runnable(new SelfType(aMethod)); - if (NS_FAILED(runnable->Init(aInitOp))) { - return nullptr; - } - return runnable.forget(); - } - - template <typename InitOp> - static void - Dispatch(Res (ObjectType::*aMethod)(Arg1), const InitOp& aInitOp) - { - RefPtr<SelfType> runnable = Create(aMethod, aInitOp); - if (!runnable) { - return; - } - Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable))); - } - - NS_IMETHOD Run() override - { - MOZ_ASSERT(NS_IsMainThread()); - - ObjectType* obj = ObjectWrapper::GetInstance(); - if (!obj) { - NS_WARNING("Notification handler not initialized"); - } else { - ((*obj).*mMethod)(ConvertArg<Arg1>(mArg1)); - } - return NS_OK; - } - -private: - DaemonNotificationRunnable1(Res (ObjectType::*aMethod)(Arg1)) - : mMethod(aMethod) - { - MOZ_ASSERT(mMethod); - } - - template<typename InitOp> - nsresult Init(const InitOp& aInitOp) - { - nsresult rv = aInitOp(mArg1); - if (NS_FAILED(rv)) { - return rv; - } - return NS_OK; - } - - Res (ObjectType::*mMethod)(Arg1); - Tin1 mArg1; -}; - -template <typename ObjectWrapper, typename Res, - typename Tin1, typename Tin2, - typename Arg1=Tin1, typename Arg2=Tin2> -class DaemonNotificationRunnable2 final : public details::DaemonRunnable -{ -public: - typedef typename ObjectWrapper::ObjectType ObjectType; - typedef DaemonNotificationRunnable2<ObjectWrapper, Res, - Tin1, Tin2, - Arg1, Arg2> SelfType; - - template <typename InitOp> - static already_AddRefed<SelfType> - Create(Res (ObjectType::*aMethod)(Arg1, Arg2), const InitOp& aInitOp) - { - RefPtr<SelfType> runnable(new SelfType(aMethod)); - if (NS_FAILED(runnable->Init(aInitOp))) { - return nullptr; - } - return runnable.forget(); - } - - template <typename InitOp> - static void - Dispatch(Res (ObjectType::*aMethod)(Arg1, Arg2), const InitOp& aInitOp) - { - RefPtr<SelfType> runnable = Create(aMethod, aInitOp); - if (!runnable) { - return; - } - Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable))); - } - - NS_IMETHOD Run() override - { - MOZ_ASSERT(NS_IsMainThread()); - - ObjectType* obj = ObjectWrapper::GetInstance(); - if (!obj) { - NS_WARNING("Notification handler not initialized"); - } else { - ((*obj).*mMethod)(ConvertArg<Arg1>(mArg1), - ConvertArg<Arg2>(mArg2)); - } - return NS_OK; - } - -private: - DaemonNotificationRunnable2( - Res (ObjectType::*aMethod)(Arg1, Arg2)) - : mMethod(aMethod) - { - MOZ_ASSERT(mMethod); - } - - template<typename InitOp> - nsresult Init(const InitOp& aInitOp) - { - nsresult rv = aInitOp(mArg1, mArg2); - if (NS_FAILED(rv)) { - return rv; - } - return NS_OK; - } - - Res (ObjectType::*mMethod)(Arg1, Arg2); - Tin1 mArg1; - Tin2 mArg2; -}; - -template <typename ObjectWrapper, typename Res, - typename Tin1, typename Tin2, typename Tin3, - typename Arg1=Tin1, typename Arg2=Tin2, typename Arg3=Tin3> -class DaemonNotificationRunnable3 final : public details::DaemonRunnable -{ -public: - typedef typename ObjectWrapper::ObjectType ObjectType; - typedef DaemonNotificationRunnable3<ObjectWrapper, Res, - Tin1, Tin2, Tin3, - Arg1, Arg2, Arg3> SelfType; - - template <typename InitOp> - static already_AddRefed<SelfType> - Create(Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3), const InitOp& aInitOp) - { - RefPtr<SelfType> runnable(new SelfType(aMethod)); - if (NS_FAILED(runnable->Init(aInitOp))) { - return nullptr; - } - return runnable.forget(); - } - - template <typename InitOp> - static void - Dispatch(Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3), - const InitOp& aInitOp) - { - RefPtr<SelfType> runnable = Create(aMethod, aInitOp); - if (!runnable) { - return; - } - Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable))); - } - - NS_IMETHOD Run() override - { - MOZ_ASSERT(NS_IsMainThread()); - - ObjectType* obj = ObjectWrapper::GetInstance(); - if (!obj) { - NS_WARNING("Notification handler not initialized"); - } else { - ((*obj).*mMethod)(ConvertArg<Arg1>(mArg1), - ConvertArg<Arg2>(mArg2), - ConvertArg<Arg3>(mArg3)); - } - return NS_OK; - } - -private: - DaemonNotificationRunnable3( - Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3)) - : mMethod(aMethod) - { - MOZ_ASSERT(mMethod); - } - - template<typename InitOp> - nsresult Init(const InitOp& aInitOp) - { - nsresult rv = aInitOp(mArg1, mArg2, mArg3); - if (NS_FAILED(rv)) { - return rv; - } - return NS_OK; - } - - Res (ObjectType::*mMethod)(Arg1, Arg2, Arg3); - Tin1 mArg1; - Tin2 mArg2; - Tin3 mArg3; -}; - -template <typename ObjectWrapper, typename Res, - typename Tin1, typename Tin2, typename Tin3, typename Tin4, - typename Arg1=Tin1, typename Arg2=Tin2, - typename Arg3=Tin3, typename Arg4=Tin4> -class DaemonNotificationRunnable4 final : public details::DaemonRunnable -{ -public: - typedef typename ObjectWrapper::ObjectType ObjectType; - typedef DaemonNotificationRunnable4<ObjectWrapper, Res, - Tin1, Tin2, Tin3, Tin4, Arg1, Arg2, Arg3, Arg4> SelfType; - - template <typename InitOp> - static already_AddRefed<SelfType> Create( - Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4), - const InitOp& aInitOp) - { - RefPtr<SelfType> runnable(new SelfType(aMethod)); - if (NS_FAILED(runnable->Init(aInitOp))) { - return nullptr; - } - return runnable.forget(); - } - - template <typename InitOp> - static void - Dispatch(Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4), - const InitOp& aInitOp) - { - RefPtr<SelfType> runnable = Create(aMethod, aInitOp); - if (!runnable) { - return; - } - Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable))); - } - - NS_IMETHOD Run() override - { - MOZ_ASSERT(NS_IsMainThread()); - - ObjectType* obj = ObjectWrapper::GetInstance(); - if (!obj) { - NS_WARNING("Notification handler not initialized"); - } else { - ((*obj).*mMethod)(ConvertArg<Arg1>(mArg1), - ConvertArg<Arg2>(mArg2), - ConvertArg<Arg3>(mArg3), - ConvertArg<Arg4>(mArg4)); - } - return NS_OK; - } - -private: - DaemonNotificationRunnable4( - Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4)) - : mMethod(aMethod) - { - MOZ_ASSERT(mMethod); - } - - template<typename InitOp> - nsresult Init(const InitOp& aInitOp) - { - nsresult rv = aInitOp(mArg1, mArg2, mArg3, mArg4); - if (NS_FAILED(rv)) { - return rv; - } - return NS_OK; - } - - Res (ObjectType::*mMethod)(Arg1, Arg2, Arg3, Arg4); - Tin1 mArg1; - Tin2 mArg2; - Tin3 mArg3; - Tin4 mArg4; -}; - -template <typename ObjectWrapper, typename Res, - typename Tin1, typename Tin2, typename Tin3, - typename Tin4, typename Tin5, - typename Arg1=Tin1, typename Arg2=Tin2, typename Arg3=Tin3, - typename Arg4=Tin4, typename Arg5=Tin5> -class DaemonNotificationRunnable5 final : public details::DaemonRunnable -{ -public: - typedef typename ObjectWrapper::ObjectType ObjectType; - typedef DaemonNotificationRunnable5<ObjectWrapper, Res, - Tin1, Tin2, Tin3, Tin4, Tin5, Arg1, Arg2, Arg3, Arg4, Arg5> SelfType; - - template <typename InitOp> - static already_AddRefed<SelfType> Create( - Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4, Arg5), - const InitOp& aInitOp) - { - RefPtr<SelfType> runnable(new SelfType(aMethod)); - if (NS_FAILED(runnable->Init(aInitOp))) { - return nullptr; - } - return runnable.forget(); - } - - template <typename InitOp> - static void - Dispatch(Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4, Arg5), - const InitOp& aInitOp) - { - RefPtr<SelfType> runnable = Create(aMethod, aInitOp); - if (!runnable) { - return; - } - Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable))); - } - - NS_IMETHOD Run() override - { - MOZ_ASSERT(NS_IsMainThread()); - - ObjectType* obj = ObjectWrapper::GetInstance(); - if (!obj) { - NS_WARNING("Notification handler not initialized"); - } else { - ((*obj).*mMethod)(ConvertArg<Arg1>(mArg1), - ConvertArg<Arg2>(mArg2), - ConvertArg<Arg3>(mArg3), - ConvertArg<Arg4>(mArg4), - ConvertArg<Arg5>(mArg5)); - } - return NS_OK; - } - -private: - DaemonNotificationRunnable5( - Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4, Arg5)) - : mMethod(aMethod) - { - MOZ_ASSERT(mMethod); - } - - template<typename InitOp> - nsresult Init(const InitOp& aInitOp) - { - nsresult rv = aInitOp(mArg1, mArg2, mArg3, mArg4, mArg5); - if (NS_FAILED(rv)) { - return rv; - } - return NS_OK; - } - - Res (ObjectType::*mMethod)(Arg1, Arg2, Arg3, Arg4, Arg5); - Tin1 mArg1; - Tin2 mArg2; - Tin3 mArg3; - Tin4 mArg4; - Tin5 mArg5; -}; - -template <typename ObjectWrapper, typename Res, - typename Tin1, typename Tin2, typename Tin3, - typename Tin4, typename Tin5, typename Tin6, - typename Arg1=Tin1, typename Arg2=Tin2, typename Arg3=Tin3, - typename Arg4=Tin4, typename Arg5=Tin5, typename Arg6=Tin6> -class DaemonNotificationRunnable6 final : public details::DaemonRunnable -{ -public: - typedef typename ObjectWrapper::ObjectType ObjectType; - typedef DaemonNotificationRunnable6<ObjectWrapper, Res, - Tin1, Tin2, Tin3, Tin4, Tin5, Tin6, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6> - SelfType; - - template <typename InitOp> - static already_AddRefed<SelfType> Create( - Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6), - const InitOp& aInitOp) - { - RefPtr<SelfType> runnable(new SelfType(aMethod)); - if (NS_FAILED(runnable->Init(aInitOp))) { - return nullptr; - } - return runnable.forget(); - } - - template <typename InitOp> - static void - Dispatch(Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6), - const InitOp& aInitOp) - { - RefPtr<SelfType> runnable = Create(aMethod, aInitOp); - if (!runnable) { - return; - } - Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable))); - } - - NS_IMETHOD Run() override - { - MOZ_ASSERT(NS_IsMainThread()); - - ObjectType* obj = ObjectWrapper::GetInstance(); - if (!obj) { - NS_WARNING("Notification handler not initialized"); - } else { - ((*obj).*mMethod)(ConvertArg<Arg1>(mArg1), - ConvertArg<Arg2>(mArg2), - ConvertArg<Arg3>(mArg3), - ConvertArg<Arg4>(mArg4), - ConvertArg<Arg5>(mArg5), - ConvertArg<Arg6>(mArg6)); - } - return NS_OK; - } - -private: - DaemonNotificationRunnable6( - Res (ObjectType::*aMethod)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)) - : mMethod(aMethod) - { - MOZ_ASSERT(mMethod); - } - - template<typename InitOp> - nsresult Init(const InitOp& aInitOp) - { - nsresult rv = aInitOp(mArg1, mArg2, mArg3, mArg4, mArg5, mArg6); - if (NS_FAILED(rv)) { - return rv; - } - return NS_OK; - } - - Res (ObjectType::*mMethod)(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6); - Tin1 mArg1; - Tin2 mArg2; - Tin3 mArg3; - Tin4 mArg4; - Tin5 mArg5; - Tin6 mArg6; -}; - -template <typename ObjectWrapper, typename Res, - typename Tin1, typename Tin2, typename Tin3, - typename Tin4, typename Tin5, typename Tin6, - typename Tin7, typename Tin8, - typename Arg1=Tin1, typename Arg2=Tin2, typename Arg3=Tin3, - typename Arg4=Tin4, typename Arg5=Tin5, typename Arg6=Tin6, - typename Arg7=Tin7, typename Arg8=Tin8> -class DaemonNotificationRunnable8 final : public details::DaemonRunnable -{ -public: - typedef typename ObjectWrapper::ObjectType ObjectType; - typedef DaemonNotificationRunnable8<ObjectWrapper, Res, - Tin1, Tin2, Tin3, Tin4, Tin5, Tin6, Tin7, Tin8, - Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8> SelfType; - - template <typename InitOp> - static already_AddRefed<SelfType> Create( - Res (ObjectType::*aMethod)( - Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8), - const InitOp& aInitOp) - { - RefPtr<SelfType> runnable(new SelfType(aMethod)); - if (NS_FAILED(runnable->Init(aInitOp))) { - return nullptr; - } - return runnable.forget(); - } - - template <typename InitOp> - static void - Dispatch( - Res (ObjectType::*aMethod)( - Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8), - const InitOp& aInitOp) - { - RefPtr<SelfType> runnable = Create(aMethod, aInitOp); - if (!runnable) { - return; - } - Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable))); - } - - NS_IMETHOD Run() override - { - MOZ_ASSERT(NS_IsMainThread()); - - ObjectType* obj = ObjectWrapper::GetInstance(); - if (!obj) { - NS_WARNING("Notification handler not initialized"); - } else { - ((*obj).*mMethod)(ConvertArg<Arg1>(mArg1), - ConvertArg<Arg2>(mArg2), - ConvertArg<Arg3>(mArg3), - ConvertArg<Arg4>(mArg4), - ConvertArg<Arg5>(mArg5), - ConvertArg<Arg6>(mArg6), - ConvertArg<Arg7>(mArg7), - ConvertArg<Arg8>(mArg8)); - } - return NS_OK; - } - -private: - DaemonNotificationRunnable8( - Res (ObjectType::*aMethod)( - Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8)) - : mMethod(aMethod) - { - MOZ_ASSERT(mMethod); - } - - template<typename InitOp> - nsresult Init(const InitOp& aInitOp) - { - nsresult rv = aInitOp(mArg1, mArg2, mArg3, mArg4, - mArg5, mArg6, mArg7, mArg8); - if (NS_FAILED(rv)) { - return rv; - } - return NS_OK; - } - - Res (ObjectType::*mMethod)( - Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8); - Tin1 mArg1; - Tin2 mArg2; - Tin3 mArg3; - Tin4 mArg4; - Tin5 mArg5; - Tin6 mArg6; - Tin7 mArg7; - Tin8 mArg8; -}; - -template <typename ObjectWrapper, typename Res, - typename Tin1, typename Tin2, typename Tin3, - typename Tin4, typename Tin5, typename Tin6, - typename Tin7, typename Tin8, typename Tin9, - typename Arg1=Tin1, typename Arg2=Tin2, typename Arg3=Tin3, - typename Arg4=Tin4, typename Arg5=Tin5, typename Arg6=Tin6, - typename Arg7=Tin7, typename Arg8=Tin8, typename Arg9=Tin9> -class DaemonNotificationRunnable9 final : public details::DaemonRunnable -{ -public: - typedef typename ObjectWrapper::ObjectType ObjectType; - typedef DaemonNotificationRunnable9<ObjectWrapper, Res, - Tin1, Tin2, Tin3, Tin4, Tin5, Tin6, Tin7, Tin8, Tin9, - Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9> SelfType; - - template <typename InitOp> - static already_AddRefed<SelfType> Create( - Res (ObjectType::*aMethod)( - Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9), - const InitOp& aInitOp) - { - RefPtr<SelfType> runnable(new SelfType(aMethod)); - if (NS_FAILED(runnable->Init(aInitOp))) { - return nullptr; - } - return runnable.forget(); - } - - template <typename InitOp> - static void - Dispatch( - Res (ObjectType::*aMethod)( - Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9), - const InitOp& aInitOp) - { - RefPtr<SelfType> runnable = Create(aMethod, aInitOp); - if (!runnable) { - return; - } - Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToMainThread(runnable))); - } - - NS_IMETHOD Run() override - { - MOZ_ASSERT(NS_IsMainThread()); - - ObjectType* obj = ObjectWrapper::GetInstance(); - if (!obj) { - NS_WARNING("Notification handler not initialized"); - } else { - ((*obj).*mMethod)(ConvertArg<Arg1>(mArg1), - ConvertArg<Arg2>(mArg2), - ConvertArg<Arg3>(mArg3), - ConvertArg<Arg4>(mArg4), - ConvertArg<Arg5>(mArg5), - ConvertArg<Arg6>(mArg6), - ConvertArg<Arg7>(mArg7), - ConvertArg<Arg8>(mArg8), - ConvertArg<Arg9>(mArg9)); - } - return NS_OK; - } - -private: - DaemonNotificationRunnable9( - Res (ObjectType::*aMethod)( - Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9)) - : mMethod(aMethod) - { - MOZ_ASSERT(mMethod); - } - - template<typename InitOp> - nsresult Init(const InitOp& aInitOp) - { - nsresult rv = aInitOp(mArg1, mArg2, mArg3, mArg4, - mArg5, mArg6, mArg7, mArg8, mArg9); - if (NS_FAILED(rv)) { - return rv; - } - return NS_OK; - } - - Res (ObjectType::*mMethod)( - Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9); - Tin1 mArg1; - Tin2 mArg2; - Tin3 mArg3; - Tin4 mArg4; - Tin5 mArg5; - Tin6 mArg6; - Tin7 mArg7; - Tin8 mArg8; - Tin9 mArg9; -}; - -} -} - -#endif // mozilla_ipc_DaemonRunnables_h diff --git a/ipc/hal/DaemonSocket.cpp b/ipc/hal/DaemonSocket.cpp deleted file mode 100644 index 94c36b955..000000000 --- a/ipc/hal/DaemonSocket.cpp +++ /dev/null @@ -1,263 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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 "DaemonSocket.h" -#include "mozilla/ipc/DaemonSocketConsumer.h" -#include "mozilla/ipc/DaemonSocketPDU.h" -#include "mozilla/UniquePtr.h" -#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, MOZ_COUNT_DTOR - -#ifdef CHROMIUM_LOG -#undef CHROMIUM_LOG -#endif - -#if defined(MOZ_WIDGET_GONK) -#include <android/log.h> -#define CHROMIUM_LOG(args...) __android_log_print(ANDROID_LOG_INFO, "I/O", args); -#else -#include <stdio.h> -#define IODEBUG true -#define CHROMIUM_LOG(args...) if (IODEBUG) printf(args); -#endif - -namespace mozilla { -namespace ipc { - -// -// DaemonSocketIO -// - -class DaemonSocketIO final : public ConnectionOrientedSocketIO -{ -public: - DaemonSocketIO(MessageLoop* aConsumerLoop, - MessageLoop* aIOLoop, - int aFd, ConnectionStatus aConnectionStatus, - UnixSocketConnector* aConnector, - DaemonSocket* aConnection, - DaemonSocketIOConsumer* aConsumer); - - ~DaemonSocketIO(); - - // Methods for |DataSocketIO| - // - - nsresult QueryReceiveBuffer(UnixSocketIOBuffer** aBuffer) override; - void ConsumeBuffer() override; - void DiscardBuffer() override; - - // Methods for |SocketIOBase| - // - - SocketBase* GetSocketBase() override; - - bool IsShutdownOnConsumerThread() const override; - bool IsShutdownOnIOThread() const override; - - void ShutdownOnConsumerThread() override; - void ShutdownOnIOThread() override; - -private: - DaemonSocket* mConnection; - DaemonSocketIOConsumer* mConsumer; - UniquePtr<DaemonSocketPDU> mPDU; - bool mShuttingDownOnIOThread; -}; - -DaemonSocketIO::DaemonSocketIO( - MessageLoop* aConsumerLoop, - MessageLoop* aIOLoop, - int aFd, - ConnectionStatus aConnectionStatus, - UnixSocketConnector* aConnector, - DaemonSocket* aConnection, - DaemonSocketIOConsumer* aConsumer) - : ConnectionOrientedSocketIO(aConsumerLoop, - aIOLoop, - aFd, - aConnectionStatus, - aConnector) - , mConnection(aConnection) - , mConsumer(aConsumer) - , mShuttingDownOnIOThread(false) -{ - MOZ_ASSERT(mConnection); - MOZ_ASSERT(mConsumer); - - MOZ_COUNT_CTOR_INHERITED(DaemonSocketIO, ConnectionOrientedSocketIO); -} - -DaemonSocketIO::~DaemonSocketIO() -{ - MOZ_COUNT_DTOR_INHERITED(DaemonSocketIO, ConnectionOrientedSocketIO); -} - -// |DataSocketIO| - -nsresult -DaemonSocketIO::QueryReceiveBuffer(UnixSocketIOBuffer** aBuffer) -{ - MOZ_ASSERT(aBuffer); - - if (!mPDU) { - /* There's only one PDU for receiving. We reuse it every time. */ - mPDU = MakeUnique<DaemonSocketPDU>(DaemonSocketPDU::PDU_MAX_PAYLOAD_LENGTH); - } - *aBuffer = mPDU.get(); - - return NS_OK; -} - -void -DaemonSocketIO::ConsumeBuffer() -{ - MOZ_ASSERT(mConsumer); - - mConsumer->Handle(*mPDU); -} - -void -DaemonSocketIO::DiscardBuffer() -{ - // Nothing to do. -} - -// |SocketIOBase| - -SocketBase* -DaemonSocketIO::GetSocketBase() -{ - return mConnection; -} - -bool -DaemonSocketIO::IsShutdownOnConsumerThread() const -{ - MOZ_ASSERT(IsConsumerThread()); - - return mConnection == nullptr; -} - -bool -DaemonSocketIO::IsShutdownOnIOThread() const -{ - return mShuttingDownOnIOThread; -} - -void -DaemonSocketIO::ShutdownOnConsumerThread() -{ - MOZ_ASSERT(IsConsumerThread()); - MOZ_ASSERT(!IsShutdownOnConsumerThread()); - - mConnection = nullptr; -} - -void -DaemonSocketIO::ShutdownOnIOThread() -{ - MOZ_ASSERT(!IsConsumerThread()); - MOZ_ASSERT(!mShuttingDownOnIOThread); - - Close(); // will also remove fd from I/O loop - mShuttingDownOnIOThread = true; -} - -// -// DaemonSocket -// - -DaemonSocket::DaemonSocket( - DaemonSocketIOConsumer* aIOConsumer, - DaemonSocketConsumer* aConsumer, - int aIndex) - : mIO(nullptr) - , mIOConsumer(aIOConsumer) - , mConsumer(aConsumer) - , mIndex(aIndex) -{ - MOZ_ASSERT(mConsumer); - - MOZ_COUNT_CTOR_INHERITED(DaemonSocket, ConnectionOrientedSocket); -} - -DaemonSocket::~DaemonSocket() -{ - MOZ_COUNT_DTOR_INHERITED(DaemonSocket, ConnectionOrientedSocket); -} - -// |ConnectionOrientedSocket| - -nsresult -DaemonSocket::PrepareAccept(UnixSocketConnector* aConnector, - MessageLoop* aConsumerLoop, - MessageLoop* aIOLoop, - ConnectionOrientedSocketIO*& aIO) -{ - MOZ_ASSERT(!mIO); - - SetConnectionStatus(SOCKET_CONNECTING); - - mIO = new DaemonSocketIO( - aConsumerLoop, aIOLoop, -1, UnixSocketWatcher::SOCKET_IS_CONNECTING, - aConnector, this, mIOConsumer); - aIO = mIO; - - return NS_OK; -} - -// |DataSocket| - -void -DaemonSocket::SendSocketData(UnixSocketIOBuffer* aBuffer) -{ - MOZ_ASSERT(mIO); - MOZ_ASSERT(mIO->IsConsumerThread()); - - mIO->GetIOLoop()->PostTask( - MakeAndAddRef<SocketIOSendTask<DaemonSocketIO, UnixSocketIOBuffer>>( - mIO, aBuffer)); -} - -// |SocketBase| - -void -DaemonSocket::Close() -{ - if (!mIO) { - CHROMIUM_LOG("HAL daemon already disconnected!"); - return; - } - - MOZ_ASSERT(mIO->IsConsumerThread()); - - mIO->ShutdownOnConsumerThread(); - mIO->GetIOLoop()->PostTask(MakeAndAddRef<SocketIOShutdownTask>(mIO)); - mIO = nullptr; - - NotifyDisconnect(); -} - -void -DaemonSocket::OnConnectSuccess() -{ - mConsumer->OnConnectSuccess(mIndex); -} - -void -DaemonSocket::OnConnectError() -{ - mConsumer->OnConnectError(mIndex); -} - -void -DaemonSocket::OnDisconnect() -{ - mConsumer->OnDisconnect(mIndex); -} - -} -} diff --git a/ipc/hal/DaemonSocket.h b/ipc/hal/DaemonSocket.h deleted file mode 100644 index 63d3a2e5c..000000000 --- a/ipc/hal/DaemonSocket.h +++ /dev/null @@ -1,63 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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/. */ - -#ifndef mozilla_ipc_DaemonSocket_h -#define mozilla_ipc_DaemonSocket_h - -#include "mozilla/ipc/ConnectionOrientedSocket.h" - -namespace mozilla { -namespace ipc { - -class DaemonSocketConsumer; -class DaemonSocketIO; -class DaemonSocketIOConsumer; - -/** - * |DaemonSocket| represents the socket to connect to the HAL daemon. It - * offers connection establishment and sending PDUs. PDU receiving is - * performed by |DaemonSocketIOConsumer|. - */ -class DaemonSocket : public ConnectionOrientedSocket -{ -public: - DaemonSocket(DaemonSocketIOConsumer* aIOConsumer, - DaemonSocketConsumer* aConsumer, - int aIndex); - virtual ~DaemonSocket(); - - // Methods for |ConnectionOrientedSocket| - // - - nsresult PrepareAccept(UnixSocketConnector* aConnector, - MessageLoop* aConsumerLoop, - MessageLoop* aIOLoop, - ConnectionOrientedSocketIO*& aIO) override; - - // Methods for |DataSocket| - // - - void SendSocketData(UnixSocketIOBuffer* aBuffer) override; - - // Methods for |SocketBase| - // - - void Close() override; - void OnConnectSuccess() override; - void OnConnectError() override; - void OnDisconnect() override; - -private: - DaemonSocketIO* mIO; - DaemonSocketIOConsumer* mIOConsumer; - DaemonSocketConsumer* mConsumer; - int mIndex; -}; - -} -} - -#endif diff --git a/ipc/hal/DaemonSocketConnector.cpp b/ipc/hal/DaemonSocketConnector.cpp deleted file mode 100644 index 97106bdd0..000000000 --- a/ipc/hal/DaemonSocketConnector.cpp +++ /dev/null @@ -1,244 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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 "DaemonSocketConnector.h" -#include <fcntl.h> -#include <limits.h> -#include <stddef.h> -#include <string.h> -#include <sys/un.h> -#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, MOZ_COUNT_DTOR -#include "prrng.h" - -#ifdef CHROMIUM_LOG -#undef CHROMIUM_LOG -#endif - -#if defined(MOZ_WIDGET_GONK) -#include <android/log.h> -#define CHROMIUM_LOG(args...) __android_log_print(ANDROID_LOG_INFO, "I/O", args); -#else -#include <stdio.h> -#define IODEBUG true -#define CHROMIUM_LOG(args...) if (IODEBUG) printf(args); -#endif - -namespace mozilla { -namespace ipc { - -nsresult -DaemonSocketConnector::CreateRandomAddressString( - const nsACString& aPrefix, unsigned long aPostfixLength, - nsACString& aAddress) -{ - static const char sHexChar[16] = { - [0x0] = '0', [0x1] = '1', [0x2] = '2', [0x3] = '3', - [0x4] = '4', [0x5] = '5', [0x6] = '6', [0x7] = '7', - [0x8] = '8', [0x9] = '9', [0xa] = 'a', [0xb] = 'b', - [0xc] = 'c', [0xd] = 'd', [0xe] = 'e', [0xf] = 'f' - }; - - unsigned short seed[3]; - - if (NS_WARN_IF(!PR_GetRandomNoise(seed, sizeof(seed)))) { - return NS_ERROR_NOT_IMPLEMENTED; - } - - aAddress = aPrefix; - aAddress.Append('-'); - - while (aPostfixLength) { - // Android doesn't provide rand_r, so we use nrand48 here, - // even though it's deprecated. - long value = nrand48(seed); - - size_t bits = sizeof(value) * CHAR_BIT; - - while ((bits > 4) && aPostfixLength) { - aAddress.Append(sHexChar[value&0xf]); - bits -= 4; - value >>= 4; - --aPostfixLength; - } - } - - return NS_OK; -} - -DaemonSocketConnector::DaemonSocketConnector(const nsACString& aSocketName) - : mSocketName(aSocketName) -{ - MOZ_COUNT_CTOR_INHERITED(DaemonSocketConnector, UnixSocketConnector); -} - -DaemonSocketConnector::~DaemonSocketConnector() -{ - MOZ_COUNT_CTOR_INHERITED(DaemonSocketConnector, UnixSocketConnector); -} - -nsresult -DaemonSocketConnector::CreateSocket(int& aFd) const -{ - aFd = socket(AF_UNIX, SOCK_SEQPACKET, 0); - if (aFd < 0) { - CHROMIUM_LOG("Could not open daemon socket!"); - return NS_ERROR_FAILURE; - } - - return NS_OK; -} - -nsresult -DaemonSocketConnector::SetSocketFlags(int aFd) const -{ - static const int sReuseAddress = 1; - - // Set close-on-exec bit. - int flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFD)); - if (flags < 0) { - return NS_ERROR_FAILURE; - } - flags |= FD_CLOEXEC; - int res = TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFD, flags)); - if (res < 0) { - return NS_ERROR_FAILURE; - } - - // Set non-blocking status flag. - flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFL)); - if (flags < 0) { - return NS_ERROR_FAILURE; - } - flags |= O_NONBLOCK; - res = TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFL, flags)); - if (res < 0) { - return NS_ERROR_FAILURE; - } - - // Set socket addr to be reused even if kernel is still waiting to close. - res = setsockopt(aFd, SOL_SOCKET, SO_REUSEADDR, &sReuseAddress, - sizeof(sReuseAddress)); - if (res < 0) { - return NS_ERROR_FAILURE; - } - - return NS_OK; -} - -nsresult -DaemonSocketConnector::CreateAddress(struct sockaddr& aAddress, - socklen_t& aAddressLength) const -{ - static const size_t sNameOffset = 1; - - struct sockaddr_un* address = - reinterpret_cast<struct sockaddr_un*>(&aAddress); - - size_t namesiz = mSocketName.Length() + 1; // include trailing '\0' - - if (NS_WARN_IF((sNameOffset + namesiz) > sizeof(address->sun_path))) { - return NS_ERROR_FAILURE; - } - - address->sun_family = AF_UNIX; - memset(address->sun_path, '\0', sNameOffset); // abstract socket - memcpy(address->sun_path + sNameOffset, mSocketName.get(), namesiz); - - aAddressLength = - offsetof(struct sockaddr_un, sun_path) + sNameOffset + namesiz; - - return NS_OK; -} - -// |UnixSocketConnector| - -nsresult -DaemonSocketConnector::ConvertAddressToString( - const struct sockaddr& aAddress, socklen_t aAddressLength, - nsACString& aAddressString) -{ - MOZ_ASSERT(aAddress.sa_family == AF_UNIX); - - const struct sockaddr_un* un = - reinterpret_cast<const struct sockaddr_un*>(&aAddress); - - size_t len = aAddressLength - offsetof(struct sockaddr_un, sun_path); - - aAddressString.Assign(un->sun_path, len); - - return NS_OK; -} - -nsresult -DaemonSocketConnector::CreateListenSocket(struct sockaddr* aAddress, - socklen_t* aAddressLength, - int& aListenFd) -{ - ScopedClose fd; - - nsresult rv = CreateSocket(fd.rwget()); - if (NS_FAILED(rv)) { - return rv; - } - rv = SetSocketFlags(fd); - if (NS_FAILED(rv)) { - return rv; - } - if (aAddress && aAddressLength) { - rv = CreateAddress(*aAddress, *aAddressLength); - if (NS_FAILED(rv)) { - return rv; - } - } - - aListenFd = fd.forget(); - - return NS_OK; -} - -nsresult -DaemonSocketConnector::AcceptStreamSocket(int aListenFd, - struct sockaddr* aAddress, - socklen_t* aAddressLength, - int& aStreamFd) -{ - ScopedClose fd( - TEMP_FAILURE_RETRY(accept(aListenFd, aAddress, aAddressLength))); - if (fd < 0) { - CHROMIUM_LOG("Cannot accept file descriptor!"); - return NS_ERROR_FAILURE; - } - nsresult rv = SetSocketFlags(fd); - if (NS_FAILED(rv)) { - return rv; - } - - aStreamFd = fd.forget(); - - return NS_OK; -} - -nsresult -DaemonSocketConnector::CreateStreamSocket(struct sockaddr* aAddress, - socklen_t* aAddressLength, - int& aStreamFd) -{ - MOZ_CRASH("|DaemonSocketConnector| does not support " - "creating stream sockets."); - return NS_ERROR_ABORT; -} - -nsresult -DaemonSocketConnector::Duplicate(UnixSocketConnector*& aConnector) -{ - aConnector = new DaemonSocketConnector(*this); - - return NS_OK; -} - -} // namespace ipc -} // namespace mozilla diff --git a/ipc/hal/DaemonSocketConnector.h b/ipc/hal/DaemonSocketConnector.h deleted file mode 100644 index b7f2b8045..000000000 --- a/ipc/hal/DaemonSocketConnector.h +++ /dev/null @@ -1,61 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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/. */ - -#ifndef mozilla_ipc_DaemonSocketConnector_h -#define mozilla_ipc_DaemonSocketConnector_h - -#include "mozilla/ipc/UnixSocketConnector.h" -#include "nsString.h" - -namespace mozilla { -namespace ipc { - -class DaemonSocketConnector final : public UnixSocketConnector -{ -public: - static nsresult CreateRandomAddressString(const nsACString& aPrefix, - unsigned long aPostfixLength, - nsACString& aAddress); - - DaemonSocketConnector(const nsACString& aSocketName); - ~DaemonSocketConnector(); - - // Methods for |UnixSocketConnector| - // - - nsresult ConvertAddressToString(const struct sockaddr& aAddress, - socklen_t aAddressLength, - nsACString& aAddressString) override; - - nsresult CreateListenSocket(struct sockaddr* aAddress, - socklen_t* aAddressLength, - int& aListenFd) override; - - nsresult AcceptStreamSocket(int aListenFd, - struct sockaddr* aAddress, - socklen_t* aAddressLen, - int& aStreamFd) override; - - nsresult CreateStreamSocket(struct sockaddr* aAddress, - socklen_t* aAddressLength, - int& aStreamFd) override; - - nsresult Duplicate(UnixSocketConnector*& aConnector) override; - -private: - nsresult CreateSocket(int& aFd) const; - nsresult SetSocketFlags(int aFd) const; - nsresult CreateAddress(struct sockaddr& aAddress, - socklen_t& aAddressLength) const; - - nsCString mSocketName; -}; - -} // namespace ipc -} // namespace mozilla - -#endif // mozilla_ipc_DaemonSocketConnector_h diff --git a/ipc/hal/DaemonSocketConsumer.cpp b/ipc/hal/DaemonSocketConsumer.cpp deleted file mode 100644 index ad57d5f57..000000000 --- a/ipc/hal/DaemonSocketConsumer.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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 "DaemonSocketConsumer.h" - -namespace mozilla { -namespace ipc { - -// -// DaemonSocketIOConsumer -// - -DaemonSocketIOConsumer::DaemonSocketIOConsumer() -{ } - -DaemonSocketIOConsumer::~DaemonSocketIOConsumer() -{ } - -// -// DaemonSocketConsumer -// - -DaemonSocketConsumer::DaemonSocketConsumer() -{ } - -DaemonSocketConsumer::~DaemonSocketConsumer() -{ } - -} -} diff --git a/ipc/hal/DaemonSocketConsumer.h b/ipc/hal/DaemonSocketConsumer.h deleted file mode 100644 index ababab893..000000000 --- a/ipc/hal/DaemonSocketConsumer.h +++ /dev/null @@ -1,68 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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/. */ - -#ifndef mozilla_ipc_DaemonSocketConsumer_h -#define mozilla_ipc_DaemonSocketConsumer_h - -namespace mozilla { -namespace ipc { - -class DaemonSocketPDU; - -/** - * |DaemonSocketIOConsumer| processes incoming PDUs from the - * HAL daemon. Please note that its method |Handle| runs on a - * different than the consumer thread. - */ -class DaemonSocketIOConsumer -{ -public: - virtual ~DaemonSocketIOConsumer(); - - virtual void Handle(DaemonSocketPDU& aPDU) = 0; - virtual void StoreResultHandler(const DaemonSocketPDU& aPDU) = 0; - -protected: - DaemonSocketIOConsumer(); -}; - -/** - * |DaemonSocketConsumer| handles socket events. - */ -class DaemonSocketConsumer -{ -public: - /** - * Callback for socket success. Consumer-thread only. - * - * @param aIndex The index that has been given to the stream socket. - */ - virtual void OnConnectSuccess(int aIndex) = 0; - - /** - * Callback for socket errors. Consumer-thread only. - * - * @param aIndex The index that has been given to the stream socket. - */ - virtual void OnConnectError(int aIndex) = 0; - - /** - * Callback for socket disconnect. Consumer-thread only. - * - * @param aIndex The index that has been given to the stream socket. - */ - virtual void OnDisconnect(int aIndex) = 0; - -protected: - DaemonSocketConsumer(); - virtual ~DaemonSocketConsumer(); -}; - -} -} - -#endif - diff --git a/ipc/hal/DaemonSocketMessageHandlers.h b/ipc/hal/DaemonSocketMessageHandlers.h deleted file mode 100644 index 184e687f1..000000000 --- a/ipc/hal/DaemonSocketMessageHandlers.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- 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/. */ - -/* - * Message handlers - * - * This file contains base classes for message handling. - */ - -#ifndef mozilla_ipc_DaemonSocketMessageHandlers_h -#define mozilla_ipc_DaemonSocketMessageHandlers_h - -#include "nsISupportsImpl.h" // for ref-counting - -namespace mozilla { -namespace ipc { - -/** - * |DaemonSocketResultHandler| is the base class for all protocol-specific - * result handlers. It currently only manages the reference counting. - */ -class DaemonSocketResultHandler -{ -public: - NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DaemonSocketResultHandler); - -protected: - DaemonSocketResultHandler() - { } - virtual ~DaemonSocketResultHandler() - { } -}; - -} // namespace ipc -} // namespace mozilla - -#endif // mozilla_ipc_DaemonSocketMessageHandlers_h diff --git a/ipc/hal/DaemonSocketPDU.cpp b/ipc/hal/DaemonSocketPDU.cpp deleted file mode 100644 index de6aa0da7..000000000 --- a/ipc/hal/DaemonSocketPDU.cpp +++ /dev/null @@ -1,202 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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 "DaemonSocketPDU.h" -#include "mozilla/ipc/DaemonSocketConsumer.h" -#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, MOZ_COUNT_DTOR - -#ifdef CHROMIUM_LOG -#undef CHROMIUM_LOG -#endif - -#if defined(MOZ_WIDGET_GONK) -#include <android/log.h> -#define CHROMIUM_LOG(args...) __android_log_print(ANDROID_LOG_INFO, "I/O", args); -#else -#include <stdio.h> -#define IODEBUG true -#define CHROMIUM_LOG(args...) if (IODEBUG) printf(args); -#endif - -namespace mozilla { -namespace ipc { - -// -// DaemonSocketPDU -// - -DaemonSocketPDU::DaemonSocketPDU(uint8_t aService, uint8_t aOpcode, - uint16_t aPayloadSize) - : mConsumer(nullptr) -{ - MOZ_COUNT_CTOR_INHERITED(DaemonSocketPDU, UnixSocketIOBuffer); - - // Allocate memory - size_t availableSpace = PDU_HEADER_SIZE + aPayloadSize; - ResetBuffer(new uint8_t[availableSpace], 0, 0, availableSpace); - - // Reserve PDU header - uint8_t* data = Append(PDU_HEADER_SIZE); - MOZ_ASSERT(data); - - // Setup PDU header - data[PDU_OFF_SERVICE] = aService; - data[PDU_OFF_OPCODE] = aOpcode; - memcpy(data + PDU_OFF_LENGTH, &aPayloadSize, sizeof(aPayloadSize)); -} - -DaemonSocketPDU::DaemonSocketPDU(size_t aPayloadSize) - : mConsumer(nullptr) -{ - MOZ_COUNT_CTOR_INHERITED(DaemonSocketPDU, UnixSocketIOBuffer); - - size_t availableSpace = PDU_HEADER_SIZE + aPayloadSize; - ResetBuffer(new uint8_t[availableSpace], 0, 0, availableSpace); -} - -DaemonSocketPDU::~DaemonSocketPDU() -{ - MOZ_COUNT_DTOR_INHERITED(DaemonSocketPDU, UnixSocketIOBuffer); - - UniquePtr<uint8_t[]> data(GetBuffer()); - ResetBuffer(nullptr, 0, 0, 0); -} - -void -DaemonSocketPDU::GetHeader(uint8_t& aService, uint8_t& aOpcode, - uint16_t& aPayloadSize) -{ - memcpy(&aService, GetData(PDU_OFF_SERVICE), sizeof(aService)); - memcpy(&aOpcode, GetData(PDU_OFF_OPCODE), sizeof(aOpcode)); - memcpy(&aPayloadSize, GetData(PDU_OFF_LENGTH), sizeof(aPayloadSize)); -} - -ssize_t -DaemonSocketPDU::Send(int aFd) -{ - struct iovec iv; - memset(&iv, 0, sizeof(iv)); - iv.iov_base = GetData(GetLeadingSpace()); - iv.iov_len = GetSize(); - - struct msghdr msg; - memset(&msg, 0, sizeof(msg)); - msg.msg_iov = &iv; - msg.msg_iovlen = 1; - msg.msg_control = nullptr; - msg.msg_controllen = 0; - - ssize_t res = TEMP_FAILURE_RETRY(sendmsg(aFd, &msg, 0)); - if (res < 0) { - MOZ_ASSERT(errno != EBADF); /* internal error */ - OnError("sendmsg", errno); - return -1; - } - - Consume(res); - - if (mConsumer) { - // We successfully sent a PDU, now store the - // result handler in the consumer. - mConsumer->StoreResultHandler(*this); - } - - return res; -} - -#define CMSGHDR_CONTAINS_FD(_cmsghdr) \ - ( ((_cmsghdr)->cmsg_level == SOL_SOCKET) && \ - ((_cmsghdr)->cmsg_type == SCM_RIGHTS) ) - -ssize_t -DaemonSocketPDU::Receive(int aFd) -{ - struct iovec iv; - memset(&iv, 0, sizeof(iv)); - iv.iov_base = GetData(0); - iv.iov_len = GetAvailableSpace(); - - uint8_t cmsgbuf[CMSG_SPACE(sizeof(int)* MAX_NFDS)]; - - struct msghdr msg; - memset(&msg, 0, sizeof(msg)); - msg.msg_iov = &iv; - msg.msg_iovlen = 1; - msg.msg_control = cmsgbuf; - msg.msg_controllen = sizeof(cmsgbuf); - - ssize_t res = TEMP_FAILURE_RETRY(recvmsg(aFd, &msg, MSG_NOSIGNAL)); - if (res < 0) { - MOZ_ASSERT(errno != EBADF); /* internal error */ - OnError("recvmsg", errno); - return -1; - } - if (msg.msg_flags & (MSG_CTRUNC | MSG_OOB | MSG_ERRQUEUE)) { - return -1; - } - - SetRange(0, res); - - struct cmsghdr* chdr = CMSG_FIRSTHDR(&msg); - - for (; chdr; chdr = CMSG_NXTHDR(&msg, chdr)) { - if (NS_WARN_IF(!CMSGHDR_CONTAINS_FD(chdr))) { - continue; - } - // Retrieve sent file descriptors. - size_t fdCount = (chdr->cmsg_len - CMSG_ALIGN(sizeof(struct cmsghdr))) / sizeof(int); - for (size_t i = 0; i < fdCount; i++) { - int* receivedFd = static_cast<int*>(CMSG_DATA(chdr)) + i; - mReceivedFds.AppendElement(*receivedFd); - } - } - - return res; -} - -nsTArray<int> -DaemonSocketPDU::AcquireFds() -{ - // Forget all RAII object to avoid closing the fds. - nsTArray<int> fds; - for (auto& fd : mReceivedFds) { - fds.AppendElement(fd.forget()); - } - mReceivedFds.Clear(); - return fds; -} - -nsresult -DaemonSocketPDU::UpdateHeader() -{ - size_t len = GetPayloadSize(); - if (len >= PDU_MAX_PAYLOAD_LENGTH) { - return NS_ERROR_ILLEGAL_VALUE; - } - uint16_t len16 = static_cast<uint16_t>(len); - - memcpy(GetData(PDU_OFF_LENGTH), &len16, sizeof(len16)); - - return NS_OK; -} - -size_t -DaemonSocketPDU::GetPayloadSize() const -{ - MOZ_ASSERT(GetSize() >= PDU_HEADER_SIZE); - - return GetSize() - PDU_HEADER_SIZE; -} - -void -DaemonSocketPDU::OnError(const char* aFunction, int aErrno) -{ - CHROMIUM_LOG("%s failed with error %d (%s)", - aFunction, aErrno, strerror(aErrno)); -} - -} -} diff --git a/ipc/hal/DaemonSocketPDU.h b/ipc/hal/DaemonSocketPDU.h deleted file mode 100644 index ebc4e4419..000000000 --- a/ipc/hal/DaemonSocketPDU.h +++ /dev/null @@ -1,94 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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/. */ - -#ifndef mozilla_ipc_DaemonSocketPDU_h -#define mozilla_ipc_DaemonSocketPDU_h - -#include "mozilla/FileUtils.h" -#include "mozilla/ipc/SocketBase.h" -#include "mozilla/ipc/DaemonSocketMessageHandlers.h" -#include "nsTArray.h" - -namespace mozilla { -namespace ipc { - -static const size_t MAX_NFDS = 16; -class DaemonSocketIOConsumer; - -/** - * |DaemonSocketPDU| represents a single PDU that is transfered from or to - * the HAL daemon. Each PDU contains exactly one command. - * - * A PDU as the following format - * - * | 1 | 1 | 2 | n | - * | service | opcode | payload length | payload | - * - * Service and Opcode each require 1 byte, the payload length requires 2 - * bytes, and the payload requires the number of bytes as stored in the - * payload-length field. - * - * Each service and opcode can have a different payload with individual - * length. For the exact details of the HAL protocol, please refer to - * - * https://git.kernel.org/cgit/bluetooth/bluez.git/tree/android/hal-ipc-api.txt?id=5.24 - * - */ -class DaemonSocketPDU final : public UnixSocketIOBuffer -{ -public: - enum { - PDU_OFF_SERVICE = 0, - PDU_OFF_OPCODE = 1, - PDU_OFF_LENGTH = 2, - PDU_OFF_PAYLOAD = 4, - PDU_HEADER_SIZE = PDU_OFF_PAYLOAD, - PDU_MAX_PAYLOAD_LENGTH = 1 << 16 - }; - - DaemonSocketPDU(uint8_t aService, uint8_t aOpcode, uint16_t aPayloadSize); - DaemonSocketPDU(size_t aPayloadSize); - ~DaemonSocketPDU(); - - void SetConsumer(DaemonSocketIOConsumer* aConsumer) - { - mConsumer = aConsumer; - } - - void SetResultHandler(DaemonSocketResultHandler* aRes) - { - mRes = aRes; - } - - DaemonSocketResultHandler* GetResultHandler() const - { - return mRes; - } - - void GetHeader(uint8_t& aService, uint8_t& aOpcode, - uint16_t& aPayloadSize); - - ssize_t Send(int aFd) override; - ssize_t Receive(int aFd) override; - - nsTArray<int> AcquireFds(); - - nsresult UpdateHeader(); - -private: - size_t GetPayloadSize() const; - void OnError(const char* aFunction, int aErrno); - - DaemonSocketIOConsumer* mConsumer; - RefPtr<DaemonSocketResultHandler> mRes; - nsTArray<ScopedClose> mReceivedFds; -}; - -} -} - -#endif - diff --git a/ipc/hal/DaemonSocketPDUHelpers.cpp b/ipc/hal/DaemonSocketPDUHelpers.cpp deleted file mode 100644 index 6aaf21c33..000000000 --- a/ipc/hal/DaemonSocketPDUHelpers.cpp +++ /dev/null @@ -1,335 +0,0 @@ -/* -*- 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 "DaemonSocketPDUHelpers.h" -#include <limits> - -// Enable this constant to abort Gecko on IPC errors. This is helpful -// for debugging, but should *never* be enabled by default. -#define MOZ_HAL_ABORT_ON_IPC_ERRORS (0) - -#ifdef CHROMIUM_LOG -#undef CHROMIUM_LOG -#endif - -#if defined(MOZ_WIDGET_GONK) - -#include <android/log.h> - -#define CHROMIUM_LOG(args...) \ - __android_log_print(ANDROID_LOG_INFO, "HAL-IPC", args); - -#define CHROMIUM_LOG_VA(fmt, ap) \ - __android_log_vprint(ANDROID_LOG_INFO, "HAL-IPC", fmt, ap); - -#else - -#include <stdio.h> - -#define IODEBUG true -#define CHROMIUM_LOG(args...) if (IODEBUG) { printf(args); } -#define CHROMIUM_LOG_VA(fmt, ap) if (IODEBUG) { vprintf(fmt, ap); } - -#endif - -namespace mozilla { -namespace ipc { -namespace DaemonSocketPDUHelpers { - -// -// Logging -// - -namespace detail { - -void -LogProtocolError(const char* aFmt, ...) -{ - va_list ap; - - va_start(ap, aFmt); - CHROMIUM_LOG_VA(aFmt, ap); - va_end(ap); - - if (MOZ_HAL_ABORT_ON_IPC_ERRORS) { - MOZ_CRASH("HAL IPC protocol error"); - } -} - -} // namespace detail - -// -// Conversion -// - -nsresult -Convert(bool aIn, uint8_t& aOut) -{ - static const uint8_t sValue[] = { - [false] = 0x00, - [true] = 0x01 - }; - if (MOZ_HAL_IPC_CONVERT_WARN_IF( - aIn >= MOZ_ARRAY_LENGTH(sValue), bool, uint8_t)) { - aOut = 0; - return NS_ERROR_ILLEGAL_VALUE; - } - aOut = sValue[aIn]; - return NS_OK; -} - -nsresult -Convert(bool aIn, int32_t& aOut) -{ - uint8_t out; - nsresult rv = Convert(aIn, out); - if (NS_FAILED(rv)) { - out = 0; // silence compiler warning - return rv; - } - aOut = static_cast<int32_t>(out); - return NS_OK; -} - -nsresult -Convert(int aIn, uint8_t& aOut) -{ - if (MOZ_HAL_IPC_CONVERT_WARN_IF( - aIn < std::numeric_limits<uint8_t>::min(), int, uint8_t) || - MOZ_HAL_IPC_CONVERT_WARN_IF( - aIn > std::numeric_limits<uint8_t>::max(), int, uint8_t)) { - aOut = 0; // silences compiler warning - return NS_ERROR_ILLEGAL_VALUE; - } - aOut = static_cast<uint8_t>(aIn); - return NS_OK; -} - -nsresult -Convert(int aIn, int16_t& aOut) -{ - if (MOZ_HAL_IPC_CONVERT_WARN_IF( - aIn < std::numeric_limits<int16_t>::min(), int, int16_t) || - MOZ_HAL_IPC_CONVERT_WARN_IF( - aIn > std::numeric_limits<int16_t>::max(), int, int16_t)) { - aOut = 0; // silences compiler warning - return NS_ERROR_ILLEGAL_VALUE; - } - aOut = static_cast<int16_t>(aIn); - return NS_OK; -} - -nsresult -Convert(int aIn, int32_t& aOut) -{ - if (MOZ_HAL_IPC_CONVERT_WARN_IF( - aIn < std::numeric_limits<int32_t>::min(), int, int32_t) || - MOZ_HAL_IPC_CONVERT_WARN_IF( - aIn > std::numeric_limits<int32_t>::max(), int, int32_t)) { - aOut = 0; // silences compiler warning - return NS_ERROR_ILLEGAL_VALUE; - } - aOut = static_cast<int32_t>(aIn); - return NS_OK; -} - -nsresult -Convert(uint8_t aIn, bool& aOut) -{ - static const bool sBool[] = { - [0x00] = false, - [0x01] = true - }; - if (MOZ_HAL_IPC_CONVERT_WARN_IF( - aIn >= MOZ_ARRAY_LENGTH(sBool), uint8_t, bool)) { - return NS_ERROR_ILLEGAL_VALUE; - } - aOut = sBool[aIn]; - return NS_OK; -} - -nsresult -Convert(uint8_t aIn, char& aOut) -{ - aOut = static_cast<char>(aIn); - return NS_OK; -} - -nsresult -Convert(uint8_t aIn, int& aOut) -{ - aOut = static_cast<int>(aIn); - return NS_OK; -} - -nsresult -Convert(uint8_t aIn, unsigned long& aOut) -{ - aOut = static_cast<unsigned long>(aIn); - return NS_OK; -} - -nsresult -Convert(uint32_t aIn, int& aOut) -{ - aOut = static_cast<int>(aIn); - return NS_OK; -} - -nsresult -Convert(uint32_t aIn, uint8_t& aOut) -{ - if (MOZ_HAL_IPC_CONVERT_WARN_IF( - aIn < std::numeric_limits<uint8_t>::min(), uint32_t, uint8_t) || - MOZ_HAL_IPC_CONVERT_WARN_IF( - aIn > std::numeric_limits<uint8_t>::max(), uint32_t, uint8_t)) { - aOut = 0; // silences compiler warning - return NS_ERROR_ILLEGAL_VALUE; - } - aOut = static_cast<uint8_t>(aIn); - return NS_OK; -} - -nsresult -Convert(size_t aIn, uint16_t& aOut) -{ - if (MOZ_HAL_IPC_CONVERT_WARN_IF(aIn >= (1ul << 16), size_t, uint16_t)) { - aOut = 0; // silences compiler warning - return NS_ERROR_ILLEGAL_VALUE; - } - aOut = static_cast<uint16_t>(aIn); - return NS_OK; -} - -// -// Packing -// - -nsresult -PackPDU(bool aIn, DaemonSocketPDU& aPDU) -{ - return PackPDU(PackConversion<bool, uint8_t>(aIn), aPDU); -} - -nsresult -PackPDU(const DaemonSocketPDUHeader& aIn, DaemonSocketPDU& aPDU) -{ - nsresult rv = PackPDU(aIn.mService, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn.mOpcode, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn.mLength, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - return NS_OK; -} - -// -// Unpacking -// - -nsresult -UnpackPDU(DaemonSocketPDU& aPDU, bool& aOut) -{ - return UnpackPDU(aPDU, UnpackConversion<uint8_t, bool>(aOut)); -} - -nsresult -UnpackPDU(DaemonSocketPDU& aPDU, char& aOut) -{ - return UnpackPDU(aPDU, UnpackConversion<uint8_t, char>(aOut)); -} - -nsresult -UnpackPDU(DaemonSocketPDU& aPDU, nsDependentCString& aOut) -{ - // We get a pointer to the first character in the PDU, a length - // of 1 ensures we consume the \0 byte. With 'str' pointing to - // the string in the PDU, we can copy the actual bytes. - - const char* str = reinterpret_cast<const char*>(aPDU.Consume(1)); - if (MOZ_HAL_IPC_UNPACK_WARN_IF(!str, nsDependentCString)) { - return NS_ERROR_ILLEGAL_VALUE; // end of PDU - } - - const char* end = static_cast<char*>(memchr(str, '\0', aPDU.GetSize() + 1)); - if (MOZ_HAL_IPC_UNPACK_WARN_IF(!end, nsDependentCString)) { - return NS_ERROR_ILLEGAL_VALUE; // no string terminator - } - - ptrdiff_t len = end - str; - - const uint8_t* rest = aPDU.Consume(len); - if (MOZ_HAL_IPC_UNPACK_WARN_IF(!rest, nsDependentCString)) { - // We couldn't consume bytes that should have been there. - return NS_ERROR_ILLEGAL_VALUE; - } - - aOut.Rebind(str, len); - - return NS_OK; -} - -nsresult -UnpackPDU(DaemonSocketPDU& aPDU, const UnpackCString0& aOut) -{ - nsDependentCString cstring; - - nsresult rv = UnpackPDU(aPDU, cstring); - if (NS_FAILED(rv)) { - return NS_ERROR_ILLEGAL_VALUE; - } - - aOut.mString->AssignASCII(cstring.get(), cstring.Length()); - - return NS_OK; -} - -nsresult -UnpackPDU(DaemonSocketPDU& aPDU, const UnpackString0& aOut) -{ - nsDependentCString cstring; - - nsresult rv = UnpackPDU(aPDU, cstring); - if (NS_FAILED(rv)) { - return NS_ERROR_ILLEGAL_VALUE; - } - - *aOut.mString = NS_ConvertUTF8toUTF16(cstring); - - return NS_OK; -} - -// -// Init operators -// - -void -PDUInitOp::WarnAboutTrailingData() const -{ - size_t size = mPDU->GetSize(); - - if (MOZ_LIKELY(!size)) { - return; - } - - uint8_t service, opcode; - uint16_t payloadSize; - mPDU->GetHeader(service, opcode, payloadSize); - - detail::LogProtocolError( - "Unpacked PDU of type (%x,%x) still contains %zu Bytes of data.", - service, opcode, size); -} - -} // namespace DaemonSocketPDUHelpers -} // namespace ipc -} // namespace mozilla diff --git a/ipc/hal/DaemonSocketPDUHelpers.h b/ipc/hal/DaemonSocketPDUHelpers.h deleted file mode 100644 index 38a848e46..000000000 --- a/ipc/hal/DaemonSocketPDUHelpers.h +++ /dev/null @@ -1,1283 +0,0 @@ -/* -*- 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/. */ - -#ifndef mozilla_ipc_DaemonSocketPDUHelpers_h -#define mozilla_ipc_DaemonSocketPDUHelpers_h - -#include <stdint.h> -#include "mozilla/ipc/DaemonSocketPDU.h" -#include "mozilla/UniquePtr.h" -#include "nsString.h" - -namespace mozilla { -namespace ipc { - -struct DaemonSocketPDUHeader { - DaemonSocketPDUHeader() - : mService(0x00) - , mOpcode(0x00) - , mLength(0x00) - { } - - DaemonSocketPDUHeader(uint8_t aService, uint8_t aOpcode, uint16_t aLength) - : mService(aService) - , mOpcode(aOpcode) - , mLength(aLength) - { } - - uint8_t mService; - uint8_t mOpcode; - uint16_t mLength; -}; - -namespace DaemonSocketPDUHelpers { - -// -// Logging -// -// The HAL IPC logging macros below print clear error messages for -// failed IPC operations. Use |MOZ_HAL_IPC_CONVERT_WARN_IF|, -// |MOZ_HAL_IPC_PACK_WARN_IF| and |MOZ_HAL_IPC_UNPACK_WARN_IF| to -// test for failures when processing PDUs. -// -// All macros accept the test condition as their first argument, and -// additional type information: the convert macro takes the input and -// output types, the pack macro takes the input type, and the unpack -// macro takes output type. All macros return the result of the test -// condition. If the test fails (i.e., the condition is true), they -// output a warning to the log. -// -// Don't call the functions in the detail namespace. They are helpers -// and not for general use. -// - -namespace detail { - -void -LogProtocolError(const char*, ...); - -inline bool -ConvertWarnIfImpl(const char* aFile, unsigned long aLine, - bool aCondition, const char* aExpr, const char* aIn, - const char* aOut) -{ - if (MOZ_UNLIKELY(aCondition)) { - LogProtocolError("%s:%d: Convert('%s' to '%s') failed: %s", - aFile, aLine, aIn, aOut, aExpr); - } - return aCondition; -} - -inline bool -PackWarnIfImpl(const char* aFile, unsigned long aLine, - bool aCondition, const char* aExpr, const char* aIn) -{ - if (MOZ_UNLIKELY(aCondition)) { - LogProtocolError("%s:%d: Pack('%s') failed: %s", - aFile, aLine, aIn, aExpr); - } - return aCondition; -} - -inline bool -UnpackWarnIfImpl(const char* aFile, unsigned long aLine, - bool aCondition, const char* aExpr, const char* aOut) -{ - if (MOZ_UNLIKELY(aCondition)) { - LogProtocolError("%s:%d: Unpack('%s') failed: %s", - aFile, aLine, aOut, aExpr); - } - return aCondition; -} - -} // namespace detail - -#define MOZ_HAL_IPC_CONVERT_WARN_IF(condition, in, out) \ - ::mozilla::ipc::DaemonSocketPDUHelpers::detail:: \ - ConvertWarnIfImpl(__FILE__, __LINE__, condition, #condition, #in, #out) - -#define MOZ_HAL_IPC_PACK_WARN_IF(condition, in) \ - ::mozilla::ipc::DaemonSocketPDUHelpers::detail:: \ - PackWarnIfImpl(__FILE__, __LINE__, condition, #condition, #in) - -#define MOZ_HAL_IPC_UNPACK_WARN_IF(condition, out) \ - ::mozilla::ipc::DaemonSocketPDUHelpers::detail:: \ - UnpackWarnIfImpl(__FILE__, __LINE__, condition, #condition, #out) - -// -// Conversion -// -// PDUs can only store primitive data types, such as integers or -// byte arrays. Gecko often uses more complex data types, such as -// enumators or stuctures. Conversion functions convert between -// primitive data and internal Gecko's data types during a PDU's -// packing and unpacking. -// - -nsresult -Convert(bool aIn, uint8_t& aOut); - -nsresult -Convert(bool aIn, int32_t& aOut); - -nsresult -Convert(int aIn, uint8_t& aOut); - -nsresult -Convert(int aIn, int16_t& aOut); - -nsresult -Convert(int aIn, int32_t& aOut); - -nsresult -Convert(uint8_t aIn, bool& aOut); - -nsresult -Convert(uint8_t aIn, char& aOut); - -nsresult -Convert(uint8_t aIn, int& aOut); - -nsresult -Convert(uint8_t aIn, unsigned long& aOut); - -nsresult -Convert(uint32_t aIn, int& aOut); - -nsresult -Convert(uint32_t aIn, uint8_t& aOut); - -nsresult -Convert(size_t aIn, uint16_t& aOut); - -// -// Packing -// - -// introduce link errors on non-handled data types -template <typename T> -nsresult -PackPDU(T aIn, DaemonSocketPDU& aPDU); - -nsresult -PackPDU(bool aIn, DaemonSocketPDU& aPDU); - -inline nsresult -PackPDU(uint8_t aIn, DaemonSocketPDU& aPDU) -{ - return aPDU.Write(aIn); -} - -inline nsresult -PackPDU(uint16_t aIn, DaemonSocketPDU& aPDU) -{ - return aPDU.Write(aIn); -} - -inline nsresult -PackPDU(int32_t aIn, DaemonSocketPDU& aPDU) -{ - return aPDU.Write(aIn); -} - -inline nsresult -PackPDU(uint32_t aIn, DaemonSocketPDU& aPDU) -{ - return aPDU.Write(aIn); -} - -inline nsresult -PackPDU(int64_t aIn, DaemonSocketPDU& aPDU) -{ - return aPDU.Write(aIn); -} - -inline nsresult -PackPDU(uint64_t aIn, DaemonSocketPDU& aPDU) -{ - return aPDU.Write(aIn); -} - -inline nsresult -PackPDU(float aIn, DaemonSocketPDU& aPDU) -{ - return aPDU.Write(aIn); -} - -inline nsresult -PackPDU(double aIn, DaemonSocketPDU& aPDU) -{ - return aPDU.Write(aIn); -} - -nsresult -PackPDU(const DaemonSocketPDUHeader& aIn, DaemonSocketPDU& aPDU); - -/* |PackConversion| is a helper for packing converted values. Pass - * an instance of this structure to |PackPDU| to convert a value from - * the input type to the output type and and write it to the PDU. - */ -template<typename Tin, typename Tout> -struct PackConversion { - PackConversion(const Tin& aIn) - : mIn(aIn) - { } - - const Tin& mIn; -}; - -template<typename Tin, typename Tout> -inline nsresult -PackPDU(const PackConversion<Tin, Tout>& aIn, DaemonSocketPDU& aPDU) -{ - Tout out; - - nsresult rv = Convert(aIn.mIn, out); - if (NS_FAILED(rv)) { - return rv; - } - return PackPDU(out, aPDU); -} - -/* |PackArray| is a helper for packing arrays. Pass an instance - * of this structure as the first argument to |PackPDU| to pack - * an array. The array's maximum default length is 255 elements. - */ -template <typename T> -struct PackArray -{ - PackArray(const T* aData, size_t aLength) - : mData(aData) - , mLength(aLength) - { } - - const T* mData; - size_t mLength; -}; - -/* This implementation of |PackPDU| packs the length of an array - * and the elements of the array one-by-one. - */ -template<typename T> -inline nsresult -PackPDU(const PackArray<T>& aIn, DaemonSocketPDU& aPDU) -{ - for (size_t i = 0; i < aIn.mLength; ++i) { - nsresult rv = PackPDU(aIn.mData[i], aPDU); - if (NS_FAILED(rv)) { - return rv; - } - } - return NS_OK; -} - -template<> -inline nsresult -PackPDU<uint8_t>(const PackArray<uint8_t>& aIn, DaemonSocketPDU& aPDU) -{ - /* Write raw bytes in one pass */ - return aPDU.Write(aIn.mData, aIn.mLength); -} - -template<> -inline nsresult -PackPDU<char>(const PackArray<char>& aIn, DaemonSocketPDU& aPDU) -{ - /* Write raw bytes in one pass */ - return aPDU.Write(aIn.mData, aIn.mLength); -} - -/* |PackCString0| is a helper for packing 0-terminated C string, - * including the \0 character. Pass an instance of this structure - * as the first argument to |PackPDU| to pack a string. - */ -struct PackCString0 -{ - PackCString0(const nsCString& aString) - : mString(aString) - { } - - const nsCString& mString; -}; - -/* This implementation of |PackPDU| packs a 0-terminated C string. - */ -inline nsresult -PackPDU(const PackCString0& aIn, DaemonSocketPDU& aPDU) -{ - return PackPDU( - PackArray<uint8_t>(reinterpret_cast<const uint8_t*>(aIn.mString.get()), - aIn.mString.Length() + 1), aPDU); -} - -/* |PackReversed| is a helper for packing data in reversed order. Pass an - * instance of this structure as the first argument to |PackPDU| to pack data - * in reversed order. - */ -template<typename T> -struct PackReversed -{ - PackReversed(const T& aValue) - : mValue(aValue) - { } - - const T& mValue; -}; - -/* No general rules to pack data in reversed order. Signal a link error if the - * type |T| of |PackReversed| is not defined explicitly. - */ -template<typename T> -nsresult -PackPDU(const PackReversed<T>& aIn, DaemonSocketPDU& aPDU); - -/* This implementation of |PackPDU| packs elements in |PackArray| in reversed - * order. (ex. reversed GATT UUID, see bug 1171866) - */ -template<typename U> -inline nsresult -PackPDU(const PackReversed<PackArray<U>>& aIn, DaemonSocketPDU& aPDU) -{ - for (size_t i = 0; i < aIn.mValue.mLength; ++i) { - nsresult rv = PackPDU(aIn.mValue.mData[aIn.mValue.mLength - i - 1], aPDU); - if (NS_FAILED(rv)) { - return rv; - } - } - return NS_OK; -} - -/* |PackArray<PackReversed<U>>| is a helper for packing data of each element in - * the reversed order. Pass an instance of this structure as the first argument - * to |PackPDU| to pack data of each array element in the reversed order. - * - * Unlike |PackReversed<PackArray<U>>| which packed array elements in the - * reversed order, here we use |PackReversed<U>| to pack data of each element - * of |PackArray| in the reversed order. - */ -template<typename U> -struct PackArray<PackReversed<U>> -{ - PackArray(const U* aData, size_t aLength) - : mData(aData) - , mLength(aLength) - { } - - const U* mData; - size_t mLength; -}; - -/* This implementation of |PackPDU| packs data of each element in |PackArray| - * in the reversed order. (ex. reversed GATT UUID, see bug 1171866) - */ -template<typename U> -inline nsresult -PackPDU(const PackArray<PackReversed<U>>& aIn, DaemonSocketPDU& aPDU) -{ - for (size_t i = 0; i < aIn.mLength; ++i) { - nsresult rv = PackPDU(PackReversed<U>(aIn.mData[i]), aPDU); - if (NS_FAILED(rv)) { - return rv; - } - } - return NS_OK; -} - -template <typename T1, typename T2> -inline nsresult -PackPDU(const T1& aIn1, const T2& aIn2, DaemonSocketPDU& aPDU) -{ - nsresult rv = PackPDU(aIn1, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - return PackPDU(aIn2, aPDU); -} - -template <typename T1, typename T2, typename T3> -inline nsresult -PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3, - DaemonSocketPDU& aPDU) -{ - nsresult rv = PackPDU(aIn1, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn2, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - return PackPDU(aIn3, aPDU); -} - -template <typename T1, typename T2, typename T3, typename T4> -inline nsresult -PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3, const T4& aIn4, - DaemonSocketPDU& aPDU) -{ - nsresult rv = PackPDU(aIn1, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn2, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn3, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - return PackPDU(aIn4, aPDU); -} - -template <typename T1, typename T2, typename T3, - typename T4, typename T5> -inline nsresult -PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3, - const T4& aIn4, const T5& aIn5, - DaemonSocketPDU& aPDU) -{ - nsresult rv = PackPDU(aIn1, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn2, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn3, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn4, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - return PackPDU(aIn5, aPDU); -} - -template <typename T1, typename T2, typename T3, - typename T4, typename T5, typename T6> -inline nsresult -PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3, - const T4& aIn4, const T5& aIn5, const T6& aIn6, - DaemonSocketPDU& aPDU) -{ - nsresult rv = PackPDU(aIn1, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn2, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn3, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn4, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn5, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - return PackPDU(aIn6, aPDU); -} - -template <typename T1, typename T2, typename T3, - typename T4, typename T5, typename T6, - typename T7> -inline nsresult -PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3, - const T4& aIn4, const T5& aIn5, const T6& aIn6, - const T7& aIn7, DaemonSocketPDU& aPDU) -{ - nsresult rv = PackPDU(aIn1, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn2, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn3, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn4, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn5, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn6, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - return PackPDU(aIn7, aPDU); -} - -template <typename T1, typename T2, typename T3, - typename T4, typename T5, typename T6, - typename T7, typename T8> -inline nsresult -PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3, - const T4& aIn4, const T5& aIn5, const T6& aIn6, - const T7& aIn7, const T8& aIn8, DaemonSocketPDU& aPDU) -{ - nsresult rv = PackPDU(aIn1, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn2, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn3, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn4, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn5, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn6, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn7, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - return PackPDU(aIn8, aPDU); -} - -template <typename T1, typename T2, typename T3, - typename T4, typename T5, typename T6, - typename T7, typename T8, typename T9, - typename T10, typename T11, typename T12, - typename T13> -inline nsresult -PackPDU(const T1& aIn1, const T2& aIn2, const T3& aIn3, - const T4& aIn4, const T5& aIn5, const T6& aIn6, - const T7& aIn7, const T8& aIn8, const T9& aIn9, - const T10& aIn10, const T11& aIn11, const T12& aIn12, - const T13& aIn13, DaemonSocketPDU& aPDU) -{ - nsresult rv = PackPDU(aIn1, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn2, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn3, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn4, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn5, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn6, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn7, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn8, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn9, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn10, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn11, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - rv = PackPDU(aIn12, aPDU); - if (NS_FAILED(rv)) { - return rv; - } - return PackPDU(aIn13, aPDU); -} - -// -// Unpacking -// - -// introduce link errors on non-handled data types -template <typename T> -nsresult -UnpackPDU(DaemonSocketPDU& aPDU, T& aOut); - -nsresult -UnpackPDU(DaemonSocketPDU& aPDU, bool& aOut); - -nsresult -UnpackPDU(DaemonSocketPDU& aPDU, char& aOut); - -inline nsresult -UnpackPDU(DaemonSocketPDU& aPDU, int8_t& aOut) -{ - return aPDU.Read(aOut); -} - -inline nsresult -UnpackPDU(DaemonSocketPDU& aPDU, uint8_t& aOut) -{ - return aPDU.Read(aOut); -} - -inline nsresult -UnpackPDU(DaemonSocketPDU& aPDU, uint16_t& aOut) -{ - return aPDU.Read(aOut); -} - -inline nsresult -UnpackPDU(DaemonSocketPDU& aPDU, int32_t& aOut) -{ - return aPDU.Read(aOut); -} - -inline nsresult -UnpackPDU(DaemonSocketPDU& aPDU, uint32_t& aOut) -{ - return aPDU.Read(aOut); -} - -inline nsresult -UnpackPDU(DaemonSocketPDU& aPDU, int64_t& aOut) -{ - return aPDU.Read(aOut); -} - -inline nsresult -UnpackPDU(DaemonSocketPDU& aPDU, uint64_t& aOut) -{ - return aPDU.Read(aOut); -} - -inline nsresult -UnpackPDU(DaemonSocketPDU& aPDU, float& aOut) -{ - return aPDU.Read(aOut); -} - -inline nsresult -UnpackPDU(DaemonSocketPDU& aPDU, double& aOut) -{ - return aPDU.Read(aOut); -} - -inline nsresult -UnpackPDU(DaemonSocketPDU& aPDU, DaemonSocketPDUHeader& aOut) -{ - nsresult rv = UnpackPDU(aPDU, aOut.mService); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(aPDU, aOut.mOpcode); - if (NS_FAILED(rv)) { - return rv; - } - return UnpackPDU(aPDU, aOut.mLength); -} - -nsresult -UnpackPDU(DaemonSocketPDU& aPDU, nsDependentCString& aOut); - -/* |UnpackCString0| is a helper for unpacking 0-terminated C string, - * including the \0 character. Pass an instance of this structure - * as the first argument to |UnpackPDU| to unpack a string. - */ -struct UnpackCString0 -{ - UnpackCString0(nsCString& aString) - : mString(&aString) - { } - - nsCString* mString; // non-null by construction -}; - -/* This implementation of |UnpackPDU| unpacks a 0-terminated C string. - */ -nsresult -UnpackPDU(DaemonSocketPDU& aPDU, const UnpackCString0& aOut); - -/* |UnpackString0| is a helper for unpacking 0-terminated C string, - * including the \0 character. Pass an instance of this structure - * as the first argument to |UnpackPDU| to unpack a C string and convert - * it to wide-character encoding. - */ -struct UnpackString0 -{ - UnpackString0(nsString& aString) - : mString(&aString) - { } - - nsString* mString; // non-null by construction -}; - -/* This implementation of |UnpackPDU| unpacks a 0-terminated C string - * and converts it to wide-character encoding. - */ -nsresult -UnpackPDU(DaemonSocketPDU& aPDU, const UnpackString0& aOut); - -/* |UnpackConversion| is a helper for convering unpacked values. Pass - * an instance of this structure to |UnpackPDU| to read a value from - * the PDU in the input type and convert it to the output type. - */ -template<typename Tin, typename Tout> -struct UnpackConversion { - UnpackConversion(Tout& aOut) - : mOut(aOut) - { } - - Tout& mOut; -}; - -template<typename Tin, typename Tout> -inline nsresult -UnpackPDU(DaemonSocketPDU& aPDU, const UnpackConversion<Tin, Tout>& aOut) -{ - Tin in; - nsresult rv = UnpackPDU(aPDU, in); - if (NS_FAILED(rv)) { - return rv; - } - return Convert(in, aOut.mOut); -} - -/* |UnpackArray| is a helper for unpacking arrays. Pass an instance - * of this structure as the second argument to |UnpackPDU| to unpack - * an array. - */ -template <typename T> -struct UnpackArray -{ - UnpackArray(T* aData, size_t aLength) - : mData(aData) - , mLength(aLength) - { } - - UnpackArray(UniquePtr<T[]>& aData, size_t aLength) - : mData(nullptr) - , mLength(aLength) - { - aData.reset(new T[mLength]); - mData = aData.get(); - } - - UnpackArray(UniquePtr<T>& aData, size_t aSize, size_t aElemSize) - : mData(nullptr) - , mLength(aSize / aElemSize) - { - aData.reset(new T[mLength]); - mData = aData.get(); - } - - T* mData; - size_t mLength; -}; - -template<typename T> -inline nsresult -UnpackPDU(DaemonSocketPDU& aPDU, const UnpackArray<T>& aOut) -{ - for (size_t i = 0; i < aOut.mLength; ++i) { - nsresult rv = UnpackPDU(aPDU, aOut.mData[i]); - if (NS_FAILED(rv)) { - return rv; - } - } - return NS_OK; -} - -template<typename T> -inline nsresult -UnpackPDU(DaemonSocketPDU& aPDU, UnpackArray<T>& aOut) -{ - for (size_t i = 0; i < aOut.mLength; ++i) { - nsresult rv = UnpackPDU(aPDU, aOut.mData[i]); - if (NS_FAILED(rv)) { - return rv; - } - } - return NS_OK; -} - -template<> -inline nsresult -UnpackPDU<uint8_t>(DaemonSocketPDU& aPDU, const UnpackArray<uint8_t>& aOut) -{ - /* Read raw bytes in one pass */ - return aPDU.Read(aOut.mData, aOut.mLength); -} - -template<typename T> -inline nsresult -UnpackPDU(DaemonSocketPDU& aPDU, nsTArray<T>& aOut) -{ - for (typename nsTArray<T>::size_type i = 0; i < aOut.Length(); ++i) { - nsresult rv = UnpackPDU(aPDU, aOut[i]); - if (NS_FAILED(rv)) { - return rv; - } - } - return NS_OK; -} - -/* |UnpackReversed| is a helper for unpacking data in reversed order. Pass an - * instance of this structure as the second argument to |UnpackPDU| to unpack - * data in reversed order. - */ -template<typename T> -struct UnpackReversed -{ - UnpackReversed(T& aValue) - : mValue(&aValue) - { } - - UnpackReversed(T&& aValue) - : mValue(&aValue) - { } - - T* mValue; -}; - -/* No general rules to unpack data in reversed order. Signal a link error if - * the type |T| of |UnpackReversed| is not defined explicitly. - */ -template<typename T> -nsresult -UnpackPDU(DaemonSocketPDU& aPDU, const UnpackReversed<T>& aOut); - -template<typename U> -inline nsresult -UnpackPDU(DaemonSocketPDU& aPDU, const UnpackReversed<UnpackArray<U>>& aOut) -{ - for (size_t i = 0; i < aOut.mValue->mLength; ++i) { - nsresult rv = UnpackPDU(aPDU, - aOut.mValue->mData[aOut.mValue->mLength - i - 1]); - if (NS_FAILED(rv)) { - return rv; - } - } - return NS_OK; -} - -// -// Init operators -// - -// -// Below are general-purpose init operators for Bluetooth. The classes -// of type |ConstantInitOp[1..3]| initialize results or notifications -// with constant values. -// - -template <typename T1> -class ConstantInitOp1 final -{ -public: - ConstantInitOp1(const T1& aArg1) - : mArg1(aArg1) - { } - - nsresult operator () (T1& aArg1) const - { - aArg1 = mArg1; - - return NS_OK; - } - -private: - const T1& mArg1; -}; - -template <typename T1, typename T2> -class ConstantInitOp2 final -{ -public: - ConstantInitOp2(const T1& aArg1, const T2& aArg2) - : mArg1(aArg1) - , mArg2(aArg2) - { } - - nsresult operator () (T1& aArg1, T2& aArg2) const - { - aArg1 = mArg1; - aArg2 = mArg2; - - return NS_OK; - } - -private: - const T1& mArg1; - const T2& mArg2; -}; - -template <typename T1, typename T2, typename T3> -class ConstantInitOp3 final -{ -public: - ConstantInitOp3(const T1& aArg1, const T2& aArg2, const T3& aArg3) - : mArg1(aArg1) - , mArg2(aArg2) - , mArg3(aArg3) - { } - - nsresult operator () (T1& aArg1, T2& aArg2, T3& aArg3) const - { - aArg1 = mArg1; - aArg2 = mArg2; - aArg3 = mArg3; - - return NS_OK; - } - -private: - const T1& mArg1; - const T2& mArg2; - const T3& mArg3; -}; - -// |PDUInitOP| provides functionality for init operators that unpack PDUs. -class PDUInitOp -{ -protected: - PDUInitOp(DaemonSocketPDU& aPDU) - : mPDU(&aPDU) - { } - - DaemonSocketPDU& GetPDU() const - { - return *mPDU; // cannot be nullptr - } - - void WarnAboutTrailingData() const; - -private: - DaemonSocketPDU* mPDU; // Hold pointer to allow for constant instances -}; - -// |UnpackPDUInitOp| is a general-purpose init operator for all variants -// of |DaemonResultRunnable| and |DaemonNotificationRunnable|. The call -// operators of |UnpackPDUInitOp| unpack a PDU into the supplied -// arguments. -class UnpackPDUInitOp final : private PDUInitOp -{ -public: - UnpackPDUInitOp(DaemonSocketPDU& aPDU) - : PDUInitOp(aPDU) - { } - - nsresult operator () () const - { - WarnAboutTrailingData(); - return NS_OK; - } - - template<typename T1> - nsresult operator () (T1& aArg1) const - { - nsresult rv = UnpackPDU(GetPDU(), aArg1); - if (NS_FAILED(rv)) { - return rv; - } - WarnAboutTrailingData(); - return NS_OK; - } - - template<typename T1, typename T2> - nsresult operator () (T1& aArg1, T2& aArg2) const - { - DaemonSocketPDU& pdu = GetPDU(); - - nsresult rv = UnpackPDU(pdu, aArg1); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg2); - if (NS_FAILED(rv)) { - return rv; - } - WarnAboutTrailingData(); - return NS_OK; - } - - template<typename T1, typename T2, typename T3> - nsresult operator () (T1& aArg1, T2& aArg2, T3& aArg3) const - { - DaemonSocketPDU& pdu = GetPDU(); - - nsresult rv = UnpackPDU(pdu, aArg1); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg2); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg3); - if (NS_FAILED(rv)) { - return rv; - } - WarnAboutTrailingData(); - return NS_OK; - } - - template<typename T1, typename T2, typename T3, typename T4> - nsresult operator () (T1& aArg1, T2& aArg2, T3& aArg3, T4& aArg4) const - { - DaemonSocketPDU& pdu = GetPDU(); - - nsresult rv = UnpackPDU(pdu, aArg1); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg2); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg3); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg4); - if (NS_FAILED(rv)) { - return rv; - } - WarnAboutTrailingData(); - return NS_OK; - } - - template<typename T1, typename T2, typename T3, typename T4, typename T5> - nsresult operator () (T1& aArg1, T2& aArg2, T3& aArg3, T4& aArg4, - T5& aArg5) const - { - DaemonSocketPDU& pdu = GetPDU(); - - nsresult rv = UnpackPDU(pdu, aArg1); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg2); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg3); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg4); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg5); - if (NS_FAILED(rv)) { - return rv; - } - WarnAboutTrailingData(); - return NS_OK; - } - - template<typename T1, typename T2, typename T3, typename T4, - typename T5, typename T6> - nsresult operator () (T1& aArg1, T2& aArg2, T3& aArg3, T4& aArg4, - T5& aArg5, T6& aArg6) const - { - DaemonSocketPDU& pdu = GetPDU(); - - nsresult rv = UnpackPDU(pdu, aArg1); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg2); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg3); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg4); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg5); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg6); - if (NS_FAILED(rv)) { - return rv; - } - WarnAboutTrailingData(); - return NS_OK; - } - - template<typename T1, typename T2, typename T3, typename T4, typename T5, - typename T6, typename T7> - nsresult operator () (T1& aArg1, T2& aArg2, T3& aArg3, T4& aArg4, - T5& aArg5, T6& aArg6, T7& aArg7) const - { - DaemonSocketPDU& pdu = GetPDU(); - - nsresult rv = UnpackPDU(pdu, aArg1); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg2); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg3); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg4); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg5); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg6); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg7); - if (NS_FAILED(rv)) { - return rv; - } - WarnAboutTrailingData(); - return NS_OK; - } - - template<typename T1, typename T2, typename T3, typename T4, typename T5, - typename T6, typename T7, typename T8> - nsresult operator () (T1& aArg1, T2& aArg2, T3& aArg3, T4& aArg4, - T5& aArg5, T6& aArg6, T7& aArg7, T8& aArg8) const - { - DaemonSocketPDU& pdu = GetPDU(); - - nsresult rv = UnpackPDU(pdu, aArg1); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg2); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg3); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg4); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg5); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg6); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg7); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg8); - if (NS_FAILED(rv)) { - return rv; - } - WarnAboutTrailingData(); - return NS_OK; - } - - template<typename T1, typename T2, typename T3, typename T4, typename T5, - typename T6, typename T7, typename T8, typename T9> - nsresult operator () (T1& aArg1, T2& aArg2, T3& aArg3, T4& aArg4, - T5& aArg5, T6& aArg6, T7& aArg7, T8& aArg8, - T9& aArg9) const - { - DaemonSocketPDU& pdu = GetPDU(); - - nsresult rv = UnpackPDU(pdu, aArg1); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg2); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg3); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg4); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg5); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg6); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg7); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg8); - if (NS_FAILED(rv)) { - return rv; - } - rv = UnpackPDU(pdu, aArg9); - if (NS_FAILED(rv)) { - return rv; - } - WarnAboutTrailingData(); - return NS_OK; - } -}; - -} // namespace DaemonSocketPDUHelpers - -} // namespace ipc -} // namespace mozilla - -#endif // mozilla_ipc_DaemonSocketPDUHelpers_h diff --git a/ipc/hal/moz.build b/ipc/hal/moz.build deleted file mode 100644 index e97963b1e..000000000 --- a/ipc/hal/moz.build +++ /dev/null @@ -1,27 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# 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/. - -EXPORTS.mozilla.ipc += [ - 'DaemonRunnables.h', - 'DaemonSocket.h', - 'DaemonSocketConnector.h', - 'DaemonSocketConsumer.h', - 'DaemonSocketMessageHandlers.h', - 'DaemonSocketPDU.h', - 'DaemonSocketPDUHelpers.h' -] - -UNIFIED_SOURCES += [ - 'DaemonSocket.cpp', - 'DaemonSocketConnector.cpp', - 'DaemonSocketConsumer.cpp', - 'DaemonSocketPDU.cpp', - 'DaemonSocketPDUHelpers.cpp' -] - -include('/ipc/chromium/chromium-config.mozbuild') - -FINAL_LIBRARY = 'xul' diff --git a/ipc/keystore/KeyStore.cpp b/ipc/keystore/KeyStore.cpp deleted file mode 100644 index 992bc9075..000000000 --- a/ipc/keystore/KeyStore.cpp +++ /dev/null @@ -1,986 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set sw=2 ts=2 et ft=cpp: 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 <fcntl.h> -#include <limits.h> -#include <pwd.h> -#include <sys/stat.h> -#include <sys/types.h> - -#if defined(MOZ_WIDGET_GONK) -#include <android/log.h> -#define KEYSTORE_LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gonk", args) -#else -#define KEYSTORE_LOG(args...) printf(args); -#endif - -#include "KeyStore.h" -#include "jsfriendapi.h" -#include "KeyStoreConnector.h" -#include "MainThreadUtils.h" // For NS_IsMainThread. -#include "nsICryptoHash.h" - -#include "plbase64.h" -#include "certdb.h" -#include "ScopedNSSTypes.h" - -using namespace mozilla::ipc; -#if ANDROID_VERSION >= 18 -// After Android 4.3, it uses binder to access keystore instead of unix socket. -#include <android/log.h> -#include <binder/BinderService.h> -#include <binder/IPCThreadState.h> -#include <binder/IServiceManager.h> -#include <security/keystore/include/keystore/IKeystoreService.h> -#include <security/keystore/include/keystore/keystore.h> - -using namespace android; - -namespace android { -// This class is used to make compiler happy. -class BpKeystoreService : public BpInterface<IKeystoreService> -{ -public: - BpKeystoreService(const sp<IBinder>& impl) - : BpInterface<IKeystoreService>(impl) - { - } - - virtual int32_t get(const String16& name, uint8_t** item, size_t* itemLength) {return 0;} - virtual int32_t test() {return 0;} - virtual int32_t insert(const String16& name, const uint8_t* item, size_t itemLength, int uid, int32_t flags) {return 0;} - virtual int32_t del(const String16& name, int uid) {return 0;} - virtual int32_t exist(const String16& name, int uid) {return 0;} - virtual int32_t saw(const String16& name, int uid, Vector<String16>* matches) {return 0;} - virtual int32_t reset() {return 0;} - virtual int32_t password(const String16& password) {return 0;} - virtual int32_t lock() {return 0;} - virtual int32_t unlock(const String16& password) {return 0;} - virtual int32_t zero() {return 0;} - virtual int32_t import(const String16& name, const uint8_t* data, size_t length, int uid, int32_t flags) {return 0;} - virtual int32_t sign(const String16& name, const uint8_t* data, size_t length, uint8_t** out, size_t* outLength) {return 0;} - virtual int32_t verify(const String16& name, const uint8_t* data, size_t dataLength, const uint8_t* signature, size_t signatureLength) {return 0;} - virtual int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength) {return 0;} - virtual int32_t del_key(const String16& name, int uid) {return 0;} - virtual int32_t grant(const String16& name, int32_t granteeUid) {return 0;} - virtual int32_t ungrant(const String16& name, int32_t granteeUid) {return 0;} - virtual int64_t getmtime(const String16& name) {return 0;} - virtual int32_t duplicate(const String16& srcKey, int32_t srcUid, const String16& destKey, int32_t destUid) {return 0;} - virtual int32_t clear_uid(int64_t uid) {return 0;} -#if ANDROID_VERSION >= 21 - virtual int32_t generate(const String16& name, int32_t uid, int32_t keyType, int32_t keySize, int32_t flags, Vector<sp<KeystoreArg> >* args) {return 0;} - virtual int32_t is_hardware_backed(const String16& keyType) {return 0;} - virtual int32_t reset_uid(int32_t uid) {return 0;} - virtual int32_t sync_uid(int32_t sourceUid, int32_t targetUid) {return 0;} - virtual int32_t password_uid(const String16& password, int32_t uid) {return 0;} -#elif ANDROID_VERSION == 18 - virtual int32_t generate(const String16& name, int uid, int32_t flags) {return 0;} - virtual int32_t is_hardware_backed() {return 0;} -#else - virtual int32_t generate(const String16& name, int32_t uid, int32_t keyType, int32_t keySize, int32_t flags, Vector<sp<KeystoreArg> >* args) {return 0;} - virtual int32_t is_hardware_backed(const String16& keyType) {return 0;} -#endif -}; - -IMPLEMENT_META_INTERFACE(KeystoreService, "android.security.keystore"); - -// Here comes binder requests. -status_t BnKeystoreService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) -{ - switch(code) { - case TEST: { - CHECK_INTERFACE(IKeystoreService, data, reply); - reply->writeNoException(); - reply->writeInt32(test()); - return NO_ERROR; - } break; - case GET: { - CHECK_INTERFACE(IKeystoreService, data, reply); - String16 name = data.readString16(); - String8 tmp(name); - uint8_t* data = NULL; - size_t dataLength = 0; - int32_t ret = get(name, &data, &dataLength); - - reply->writeNoException(); - if (ret == 1) { - reply->writeInt32(dataLength); - void* buf = reply->writeInplace(dataLength); - memcpy(buf, data, dataLength); - free(data); - } else { - reply->writeInt32(-1); - } - return NO_ERROR; - } break; - case GET_PUBKEY: { - CHECK_INTERFACE(IKeystoreService, data, reply); - String16 name = data.readString16(); - uint8_t* data = nullptr; - size_t dataLength = 0; - int32_t ret = get_pubkey(name, &data, &dataLength); - - reply->writeNoException(); - if (dataLength > 0 && data != nullptr) { - reply->writeInt32(dataLength); - void* buf = reply->writeInplace(dataLength); - memcpy(buf, data, dataLength); - free(data); - } else { - reply->writeInt32(-1); - } - reply->writeInt32(ret); - return NO_ERROR; - } break; - case SIGN: { - CHECK_INTERFACE(IKeystoreService, data, reply); - String16 name = data.readString16(); - ssize_t signDataSize = data.readInt32(); - const uint8_t *signData = nullptr; - if (signDataSize >= 0 && (size_t)signDataSize <= data.dataAvail()) { - signData = (const uint8_t *)data.readInplace(signDataSize); - } - - uint8_t *signResult = nullptr; - size_t signResultSize; - int32_t ret = sign(name, signData, (size_t)signDataSize, &signResult, - &signResultSize); - - reply->writeNoException(); - if (signResultSize > 0 && signResult != nullptr) { - reply->writeInt32(signResultSize); - void* buf = reply->writeInplace(signResultSize); - memcpy(buf, signResult, signResultSize); - free(signResult); - } else { - reply->writeInt32(-1); - } - reply->writeInt32(ret); - return NO_ERROR; - } break; - default: - return NO_ERROR; - } -} - -// Provide service for binder. -class KeyStoreService : public BnKeystoreService - , public nsNSSShutDownObject -{ -public: - int32_t test() { - uid_t callingUid = IPCThreadState::self()->getCallingUid(); - if (!mozilla::ipc::checkPermission(callingUid)) { - return ::PERMISSION_DENIED; - } - - return ::NO_ERROR; - } - - int32_t get(const String16& name, uint8_t** item, size_t* itemLength) { - nsNSSShutDownPreventionLock locker; - if (isAlreadyShutDown()) { - return ::SYSTEM_ERROR; - } - - uid_t callingUid = IPCThreadState::self()->getCallingUid(); - if (!mozilla::ipc::checkPermission(callingUid)) { - return ::PERMISSION_DENIED; - } - - String8 certName(name); - if (!strncmp(certName.string(), "WIFI_USERKEY_", 13)) { - return getPrivateKey(certName.string(), (const uint8_t**)item, itemLength); - } - - return getCertificate(certName.string(), (const uint8_t**)item, itemLength); - } - - int32_t insert(const String16& name, const uint8_t* item, size_t itemLength, int uid, int32_t flags) {return ::UNDEFINED_ACTION;} - int32_t del(const String16& name, int uid) {return ::UNDEFINED_ACTION;} - int32_t exist(const String16& name, int uid) {return ::UNDEFINED_ACTION;} - int32_t saw(const String16& name, int uid, Vector<String16>* matches) {return ::UNDEFINED_ACTION;} - int32_t reset() {return ::UNDEFINED_ACTION;} - int32_t password(const String16& password) {return ::UNDEFINED_ACTION;} - int32_t lock() {return ::UNDEFINED_ACTION;} - int32_t unlock(const String16& password) {return ::UNDEFINED_ACTION;} - int32_t zero() {return ::UNDEFINED_ACTION;} - int32_t import(const String16& name, const uint8_t* data, size_t length, int uid, int32_t flags) {return ::UNDEFINED_ACTION;} - int32_t sign(const String16& name, const uint8_t* data, size_t length, uint8_t** out, size_t* outLength) - { - nsNSSShutDownPreventionLock locker; - if (isAlreadyShutDown()) { - return ::SYSTEM_ERROR; - } - - uid_t callingUid = IPCThreadState::self()->getCallingUid(); - if (!mozilla::ipc::checkPermission(callingUid)) { - return ::PERMISSION_DENIED; - } - - if (data == nullptr) { - return ::SYSTEM_ERROR; - } - - String8 keyName(name); - if (!strncmp(keyName.string(), "WIFI_USERKEY_", 13)) { - return signData(keyName.string(), data, length, out, outLength); - } - - return ::UNDEFINED_ACTION; - } - - int32_t verify(const String16& name, const uint8_t* data, size_t dataLength, const uint8_t* signature, size_t signatureLength) {return ::UNDEFINED_ACTION;} - int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength) { - nsNSSShutDownPreventionLock locker; - if (isAlreadyShutDown()) { - return ::SYSTEM_ERROR; - } - - uid_t callingUid = IPCThreadState::self()->getCallingUid(); - if (!mozilla::ipc::checkPermission(callingUid)) { - return ::PERMISSION_DENIED; - } - - String8 keyName(name); - if (!strncmp(keyName.string(), "WIFI_USERKEY_", 13)) { - return getPublicKey(keyName.string(), (const uint8_t**)pubkey, pubkeyLength); - } - - return ::UNDEFINED_ACTION; - } - - int32_t del_key(const String16& name, int uid) {return ::UNDEFINED_ACTION;} - int32_t grant(const String16& name, int32_t granteeUid) {return ::UNDEFINED_ACTION;} - int32_t ungrant(const String16& name, int32_t granteeUid) {return ::UNDEFINED_ACTION;} - int64_t getmtime(const String16& name) {return ::UNDEFINED_ACTION;} - int32_t duplicate(const String16& srcKey, int32_t srcUid, const String16& destKey, int32_t destUid) {return ::UNDEFINED_ACTION;} - int32_t clear_uid(int64_t uid) {return ::UNDEFINED_ACTION;} -#if ANDROID_VERSION >= 21 - virtual int32_t generate(const String16& name, int32_t uid, int32_t keyType, int32_t keySize, int32_t flags, Vector<sp<KeystoreArg> >* args) {return ::UNDEFINED_ACTION;} - virtual int32_t is_hardware_backed(const String16& keyType) {return ::UNDEFINED_ACTION;} - virtual int32_t reset_uid(int32_t uid) {return ::UNDEFINED_ACTION;;} - virtual int32_t sync_uid(int32_t sourceUid, int32_t targetUid) {return ::UNDEFINED_ACTION;} - virtual int32_t password_uid(const String16& password, int32_t uid) {return ::UNDEFINED_ACTION;} -#elif ANDROID_VERSION == 18 - virtual int32_t generate(const String16& name, int uid, int32_t flags) {return ::UNDEFINED_ACTION;} - virtual int32_t is_hardware_backed() {return ::UNDEFINED_ACTION;} -#else - virtual int32_t generate(const String16& name, int32_t uid, int32_t keyType, int32_t keySize, int32_t flags, Vector<sp<KeystoreArg> >* args) {return ::UNDEFINED_ACTION;} - virtual int32_t is_hardware_backed(const String16& keyType) {return ::UNDEFINED_ACTION;} -#endif - -protected: - virtual void virtualDestroyNSSReference() {} - -private: - ~KeyStoreService() { - nsNSSShutDownPreventionLock locker; - if (isAlreadyShutDown()) { - return; - } - shutdown(ShutdownCalledFrom::Object); - } -}; - -} // namespace android - -void startKeyStoreService() -{ - android::sp<android::IServiceManager> sm = android::defaultServiceManager(); - android::sp<android::KeyStoreService> keyStoreService = new android::KeyStoreService(); - sm->addService(String16("android.security.keystore"), keyStoreService); -} -#else -void startKeyStoreService() { return; } -#endif - -static const char *CA_BEGIN = "-----BEGIN ", - *CA_END = "-----END ", - *CA_TAILER = "-----\n"; - -namespace mozilla { -namespace ipc { - -static const char* KEYSTORE_ALLOWED_USERS[] = { - "root", - "wifi", - NULL -}; -static const char* KEYSTORE_ALLOWED_PREFIXES[] = { - "WIFI_SERVERCERT_", - "WIFI_USERCERT_", - "WIFI_USERKEY_", - NULL -}; - -// Transform base64 certification data into DER format -void -FormatCaData(const char *aCaData, int aCaDataLength, - const char *aName, const uint8_t **aFormatData, - size_t *aFormatDataLength) -{ - size_t bufSize = strlen(CA_BEGIN) + strlen(CA_END) + strlen(CA_TAILER) * 2 + - strlen(aName) * 2 + aCaDataLength + aCaDataLength/CA_LINE_SIZE - + 2; - char *buf = (char *)malloc(bufSize); - if (!buf) { - *aFormatData = nullptr; - return; - } - - *aFormatDataLength = bufSize; - *aFormatData = (const uint8_t *)buf; - - char *ptr = buf; - size_t len; - - // Create DER header. - len = snprintf(ptr, bufSize, "%s%s%s", CA_BEGIN, aName, CA_TAILER); - ptr += len; - bufSize -= len; - - // Split base64 data in lines. - int copySize; - while (aCaDataLength > 0) { - copySize = (aCaDataLength > CA_LINE_SIZE) ? CA_LINE_SIZE : aCaDataLength; - - memcpy(ptr, aCaData, copySize); - ptr += copySize; - aCaData += copySize; - aCaDataLength -= copySize; - bufSize -= copySize; - - *ptr = '\n'; - ptr++; - bufSize--; - } - - // Create DEA tailer. - snprintf(ptr, bufSize, "%s%s%s", CA_END, aName, CA_TAILER); -} - -ResponseCode -getCertificate(const char *aCertName, const uint8_t **aCertData, - size_t *aCertDataLength) -{ - // certificate name prefix check. - if (!aCertName) { - return KEY_NOT_FOUND; - } - - const char **prefix = KEYSTORE_ALLOWED_PREFIXES; - for (; *prefix; prefix++ ) { - if (!strncmp(*prefix, aCertName, strlen(*prefix))) { - break; - } - } - if (!(*prefix)) { - return KEY_NOT_FOUND; - } - - // Get cert from NSS by name - ScopedCERTCertificate cert(CERT_FindCertByNickname(CERT_GetDefaultCertDB(), - aCertName)); - - if (!cert) { - return KEY_NOT_FOUND; - } - - char *certDER = PL_Base64Encode((const char *)cert->derCert.data, - cert->derCert.len, nullptr); - if (!certDER) { - return SYSTEM_ERROR; - } - - FormatCaData(certDER, strlen(certDER), "CERTIFICATE", aCertData, - aCertDataLength); - PL_strfree(certDER); - - if (!(*aCertData)) { - return SYSTEM_ERROR; - } - - return SUCCESS; -} - -ResponseCode getPrivateKey(const char *aKeyName, const uint8_t **aKeyData, - size_t *aKeyDataLength) -{ - *aKeyData = nullptr; - // Get corresponding user certificate nickname - char userCertName[128] = {0}; - snprintf(userCertName, sizeof(userCertName) - 1, "WIFI_USERCERT_%s", aKeyName + 13); - - // Get private key from user certificate. - ScopedCERTCertificate userCert( - CERT_FindCertByNickname(CERT_GetDefaultCertDB(), userCertName)); - if (!userCert) { - return KEY_NOT_FOUND; - } - - ScopedSECKEYPrivateKey privateKey( - PK11_FindKeyByAnyCert(userCert.get(), nullptr)); - if (!privateKey) { - return KEY_NOT_FOUND; - } - - // Export private key in PKCS#12 encrypted format, no password. - unsigned char pwstr[] = {0, 0}; - SECItem password = {siBuffer, pwstr, sizeof(pwstr)}; - ScopedSECKEYEncryptedPrivateKeyInfo encryptedPrivateKey( - PK11_ExportEncryptedPrivKeyInfo(privateKey->pkcs11Slot, - SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4, &password, privateKey, 1, - privateKey->wincx)); - - if (!encryptedPrivateKey) { - return KEY_NOT_FOUND; - } - - // Decrypt into RSA private key. - // - // Generate key for PKCS#12 encryption, we use SHA1 with 1 iteration, as the - // parameters used in PK11_ExportEncryptedPrivKeyInfo() above. - // see: PKCS#12 v1.0, B.2. - // - uint8_t DSP[192] = {0}; - memset(DSP, 0x01, 64); // Diversifier part, ID = 1 for decryption. - memset(DSP + 128, 0x00, 64); // Password part, no password. - - uint8_t *S = &DSP[64]; // Salt part. - uint8_t *salt = encryptedPrivateKey->algorithm.parameters.data + 4; - int saltLength = (int)encryptedPrivateKey->algorithm.parameters.data[3]; - if (saltLength <= 0) { - return SYSTEM_ERROR; - } - for (int i = 0; i < 64; i++) { - S[i] = salt[i % saltLength]; - } - - // Generate key by SHA-1 - nsresult rv; - nsCOMPtr<nsICryptoHash> hash = - do_CreateInstance("@mozilla.org/security/hash;1", &rv); - if (NS_FAILED(rv)) { - return SYSTEM_ERROR; - } - - rv = hash->Init(nsICryptoHash::SHA1); - if (NS_FAILED(rv)) { - return SYSTEM_ERROR; - } - - rv = hash->Update(DSP, sizeof(DSP)); - if (NS_FAILED(rv)) { - return SYSTEM_ERROR; - } - - nsCString hashResult; - rv = hash->Finish(false, hashResult); - if (NS_FAILED(rv)) { - return SYSTEM_ERROR; - } - - // First 40-bit as key for RC4. - uint8_t key[5]; - memcpy(key, hashResult.get(), sizeof(key)); - - ScopedPK11SlotInfo slot(PK11_GetInternalSlot()); - if (!slot) { - return SYSTEM_ERROR; - } - - SECItem keyItem = {siBuffer, key, sizeof(key)}; - ScopedPK11SymKey symKey(PK11_ImportSymKey(slot, CKM_RC4, PK11_OriginUnwrap, - CKA_DECRYPT, &keyItem, nullptr)); - if (!symKey) { - return SYSTEM_ERROR; - } - - // Get expected decrypted data size then allocate memory. - uint8_t *encryptedData = (uint8_t *)encryptedPrivateKey->encryptedData.data; - unsigned int encryptedDataLen = encryptedPrivateKey->encryptedData.len; - unsigned int decryptedDataLen = encryptedDataLen; - SECStatus srv = PK11_Decrypt(symKey, CKM_RC4, &keyItem, nullptr, - &decryptedDataLen, encryptedDataLen, - encryptedData, encryptedDataLen); - if (srv != SECSuccess) { - return SYSTEM_ERROR; - } - - ScopedSECItem decryptedData(::SECITEM_AllocItem(nullptr, nullptr, - decryptedDataLen)); - if (!decryptedData) { - return SYSTEM_ERROR; - } - - // Decrypt by RC4. - srv = PK11_Decrypt(symKey, CKM_RC4, &keyItem, decryptedData->data, - &decryptedDataLen, decryptedData->len, encryptedData, - encryptedDataLen); - if (srv != SECSuccess) { - return SYSTEM_ERROR; - } - - // Export key in PEM format. - char *keyPEM = PL_Base64Encode((const char *)decryptedData->data, - decryptedDataLen, nullptr); - - if (!keyPEM) { - return SYSTEM_ERROR; - } - - FormatCaData(keyPEM, strlen(keyPEM), "PRIVATE KEY", aKeyData, aKeyDataLength); - PL_strfree(keyPEM); - - if (!(*aKeyData)) { - return SYSTEM_ERROR; - } - - return SUCCESS; -} - -ResponseCode getPublicKey(const char *aKeyName, const uint8_t **aKeyData, - size_t *aKeyDataLength) -{ - *aKeyData = nullptr; - - // Get corresponding user certificate nickname - char userCertName[128] = {0}; - snprintf(userCertName, sizeof(userCertName) - 1, "WIFI_USERCERT_%s", aKeyName + 13); - - // Get public key from user certificate. - ScopedCERTCertificate userCert( - CERT_FindCertByNickname(CERT_GetDefaultCertDB(), userCertName)); - if (!userCert) { - return KEY_NOT_FOUND; - } - - // Get public key. - ScopedSECKEYPublicKey publicKey(CERT_ExtractPublicKey(userCert)); - if (!publicKey) { - return KEY_NOT_FOUND; - } - - ScopedSECItem keyItem(PK11_DEREncodePublicKey(publicKey)); - if (!keyItem) { - return KEY_NOT_FOUND; - } - - size_t bufSize = keyItem->len; - char *buf = (char *)malloc(bufSize); - if (!buf) { - return SYSTEM_ERROR; - } - - memcpy(buf, keyItem->data, bufSize); - *aKeyData = (const uint8_t *)buf; - *aKeyDataLength = bufSize; - - return SUCCESS; -} - -ResponseCode signData(const char *aKeyName, const uint8_t *data, size_t length, - uint8_t **out, size_t *outLength) -{ - *out = nullptr; - // Get corresponding user certificate nickname - char userCertName[128] = {0}; - snprintf(userCertName, sizeof(userCertName) - 1, "WIFI_USERCERT_%s", aKeyName + 13); - - // Get private key from user certificate. - ScopedCERTCertificate userCert( - CERT_FindCertByNickname(CERT_GetDefaultCertDB(), userCertName)); - if (!userCert) { - return KEY_NOT_FOUND; - } - - ScopedSECKEYPrivateKey privateKey( - PK11_FindKeyByAnyCert(userCert.get(), nullptr)); - if (!privateKey) { - return KEY_NOT_FOUND; - } - - // - // Find hash data from incoming data. - // - // Incoming data might be padded by PKCS-1 format: - // 00 01 FF FF ... FF 00 || Hash of length 36 - // If the padding part exists, we have to ignore them. - // - uint8_t *hash = (uint8_t *)data; - const size_t HASH_LENGTH = 36; - if (length < HASH_LENGTH) { - return VALUE_CORRUPTED; - } - if (hash[0] == 0x00 && hash[1] == 0x01 && hash[2] == 0xFF && hash[3] == 0xFF) { - hash += 4; - while (*hash == 0xFF) { - if (hash + HASH_LENGTH > data + length) { - return VALUE_CORRUPTED; - } - hash++; - } - if (*hash != 0x00) { - return VALUE_CORRUPTED; - } - hash++; - } - if (hash + HASH_LENGTH != data + length) { - return VALUE_CORRUPTED; - } - SECItem hashItem = {siBuffer, hash, HASH_LENGTH}; - - // Sign hash. - ScopedSECItem signItem(::SECITEM_AllocItem(nullptr, nullptr, - PK11_SignatureLen(privateKey))); - if (!signItem) { - return SYSTEM_ERROR; - } - - SECStatus srv; - srv = PK11_Sign(privateKey, signItem.get(), &hashItem); - if (srv != SECSuccess) { - return SYSTEM_ERROR; - } - - uint8_t *buf = (uint8_t *)malloc(signItem->len); - if (!buf) { - return SYSTEM_ERROR; - } - - memcpy(buf, signItem->data, signItem->len); - *out = buf; - *outLength = signItem->len; - - return SUCCESS; -} - -bool -checkPermission(uid_t uid) -{ - struct passwd *userInfo = getpwuid(uid); - for (const char **user = KEYSTORE_ALLOWED_USERS; *user; user++ ) { - if (!strcmp(*user, userInfo->pw_name)) { - return true; - } - } - - return false; -} - -// -// KeyStore -// - -KeyStore::KeyStore() -: mShutdown(false) -{ - MOZ_COUNT_CTOR(KeyStore); - ::startKeyStoreService(); - Listen(); -} - -KeyStore::~KeyStore() -{ - nsNSSShutDownPreventionLock locker; - MOZ_COUNT_DTOR(KeyStore); - - if (isAlreadyShutDown()) { - return; - } - - shutdown(ShutdownCalledFrom::Object); - - MOZ_ASSERT(!mListenSocket); - MOZ_ASSERT(!mStreamSocket); -} - -void -KeyStore::Shutdown() -{ - // We set mShutdown first, so that |OnDisconnect| won't try to reconnect. - mShutdown = true; - - if (mStreamSocket) { - mStreamSocket->Close(); - mStreamSocket = nullptr; - } - if (mListenSocket) { - mListenSocket->Close(); - mListenSocket = nullptr; - } -} - -void -KeyStore::Listen() -{ - // We only allocate one |StreamSocket|, but re-use it for every connection. - if (mStreamSocket) { - mStreamSocket->Close(); - } else { - mStreamSocket = new StreamSocket(this, STREAM_SOCKET); - } - - if (!mListenSocket) { - // We only ever allocate one |ListenSocket|... - mListenSocket = new ListenSocket(this, LISTEN_SOCKET); - mListenSocket->Listen(new KeyStoreConnector(KEYSTORE_ALLOWED_USERS), - mStreamSocket); - } else { - // ... but keep it open. - mListenSocket->Listen(mStreamSocket); - } - - ResetHandlerInfo(); -} - -void -KeyStore::ResetHandlerInfo() -{ - mHandlerInfo.state = STATE_IDLE; - mHandlerInfo.command = 0; - mHandlerInfo.paramCount = 0; - mHandlerInfo.commandPattern = nullptr; - for (int i = 0; i < MAX_PARAM; i++) { - mHandlerInfo.param[i].length = 0; - memset(mHandlerInfo.param[i].data, 0, VALUE_SIZE); - } -} - -bool -KeyStore::CheckSize(UnixSocketBuffer *aMessage, size_t aExpectSize) -{ - return (aMessage->GetSize() >= aExpectSize); -} - -ResponseCode -KeyStore::ReadCommand(UnixSocketBuffer *aMessage) -{ - if (mHandlerInfo.state != STATE_IDLE) { - NS_WARNING("Wrong state in ReadCommand()!"); - return SYSTEM_ERROR; - } - - if (!CheckSize(aMessage, 1)) { - NS_WARNING("Data size error in ReadCommand()!"); - return PROTOCOL_ERROR; - } - - mHandlerInfo.command = *aMessage->GetData(); - aMessage->Consume(1); - - // Find corrsponding command pattern - const struct ProtocolCommand *command = commands; - while (command->command && command->command != mHandlerInfo.command) { - command++; - } - - if (!command->command) { - NS_WARNING("Unsupported command!"); - return PROTOCOL_ERROR; - } - - // Get command pattern. - mHandlerInfo.commandPattern = command; - if (command->paramNum) { - // Read command parameter if needed. - mHandlerInfo.state = STATE_READ_PARAM_LEN; - } else { - mHandlerInfo.state = STATE_PROCESSING; - } - - return SUCCESS; -} - -ResponseCode -KeyStore::ReadLength(UnixSocketBuffer *aMessage) -{ - if (mHandlerInfo.state != STATE_READ_PARAM_LEN) { - NS_WARNING("Wrong state in ReadLength()!"); - return SYSTEM_ERROR; - } - - if (!CheckSize(aMessage, 2)) { - NS_WARNING("Data size error in ReadLength()!"); - return PROTOCOL_ERROR; - } - - // Read length of command parameter. - // FIXME: Depends on endianess and (sizeof(unsigned short) == 2) - unsigned short dataLength; - memcpy(&dataLength, aMessage->GetData(), 2); - aMessage->Consume(2); - mHandlerInfo.param[mHandlerInfo.paramCount].length = ntohs(dataLength); - - mHandlerInfo.state = STATE_READ_PARAM_DATA; - - return SUCCESS; -} - -ResponseCode -KeyStore::ReadData(UnixSocketBuffer *aMessage) -{ - if (mHandlerInfo.state != STATE_READ_PARAM_DATA) { - NS_WARNING("Wrong state in ReadData()!"); - return SYSTEM_ERROR; - } - - if (!CheckSize(aMessage, mHandlerInfo.param[mHandlerInfo.paramCount].length)) { - NS_WARNING("Data size error in ReadData()!"); - return PROTOCOL_ERROR; - } - - // Read command parameter. - memcpy(mHandlerInfo.param[mHandlerInfo.paramCount].data, - aMessage->GetData(), - mHandlerInfo.param[mHandlerInfo.paramCount].length); - aMessage->Consume(mHandlerInfo.param[mHandlerInfo.paramCount].length); - mHandlerInfo.paramCount++; - - if (mHandlerInfo.paramCount == mHandlerInfo.commandPattern->paramNum) { - mHandlerInfo.state = STATE_PROCESSING; - } else { - mHandlerInfo.state = STATE_READ_PARAM_LEN; - } - - return SUCCESS; -} - -// Status response -void -KeyStore::SendResponse(ResponseCode aResponse) -{ - MOZ_ASSERT(mStreamSocket); - - if (aResponse == NO_RESPONSE) - return; - - uint8_t response = (uint8_t)aResponse; - UnixSocketRawData* data = new UnixSocketRawData((const void *)&response, 1); - mStreamSocket->SendSocketData(data); -} - -// Data response -void -KeyStore::SendData(const uint8_t *aData, int aLength) -{ - MOZ_ASSERT(mStreamSocket); - - unsigned short dataLength = htons(aLength); - - UnixSocketRawData* length = new UnixSocketRawData((const void *)&dataLength, 2); - mStreamSocket->SendSocketData(length); - - UnixSocketRawData* data = new UnixSocketRawData((const void *)aData, aLength); - mStreamSocket->SendSocketData(data); -} - -// |StreamSocketConsumer|, |ListenSocketConsumer| - -void -KeyStore::ReceiveSocketData(int aIndex, UniquePtr<UnixSocketBuffer>& aMessage) -{ - MOZ_ASSERT(NS_IsMainThread()); - - // Handle request. - ResponseCode result = SUCCESS; - while (aMessage->GetSize() || - mHandlerInfo.state == STATE_PROCESSING) { - switch (mHandlerInfo.state) { - case STATE_IDLE: - result = ReadCommand(aMessage.get()); - break; - case STATE_READ_PARAM_LEN: - result = ReadLength(aMessage.get()); - break; - case STATE_READ_PARAM_DATA: - result = ReadData(aMessage.get()); - break; - case STATE_PROCESSING: - if (mHandlerInfo.command == 'g') { - result = SYSTEM_ERROR; - - nsNSSShutDownPreventionLock locker; - if (isAlreadyShutDown()) { - break; - } - - // Get CA - const uint8_t *data; - size_t dataLength; - const char *name = (const char *)mHandlerInfo.param[0].data; - - if (!strncmp(name, "WIFI_USERKEY_", 13)) { - result = getPrivateKey(name, &data, &dataLength); - } else { - result = getCertificate(name, &data, &dataLength); - } - if (result != SUCCESS) { - break; - } - - SendResponse(SUCCESS); - SendData(data, (int)dataLength); - - free((void *)data); - } - - ResetHandlerInfo(); - break; - } - - if (result != SUCCESS) { - SendResponse(result); - ResetHandlerInfo(); - return; - } - } -} - -void -KeyStore::OnConnectSuccess(int aIndex) -{ - if (aIndex == STREAM_SOCKET) { - mShutdown = false; - } -} - -void -KeyStore::OnConnectError(int aIndex) -{ - if (mShutdown) { - return; - } - - if (aIndex == STREAM_SOCKET) { - // Stream socket error; start listening again - Listen(); - } -} - -void -KeyStore::OnDisconnect(int aIndex) -{ - if (mShutdown) { - return; - } - - switch (aIndex) { - case LISTEN_SOCKET: - // Listen socket disconnected; start anew. - mListenSocket = nullptr; - Listen(); - break; - case STREAM_SOCKET: - // Stream socket disconnected; start listening again. - Listen(); - break; - } -} - -} // namespace ipc -} // namespace mozilla diff --git a/ipc/keystore/KeyStore.h b/ipc/keystore/KeyStore.h deleted file mode 100644 index c6bb09023..000000000 --- a/ipc/keystore/KeyStore.h +++ /dev/null @@ -1,141 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set sw=2 ts=2 et ft=cpp: 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/. */ - -#ifndef mozilla_ipc_KeyStore_h -#define mozilla_ipc_KeyStore_h 1 - -#include <sys/socket.h> -#include <sys/un.h> -#include "cert.h" -#include "mozilla/ipc/ListenSocket.h" -#include "mozilla/ipc/ListenSocketConsumer.h" -#include "mozilla/ipc/StreamSocket.h" -#include "mozilla/ipc/StreamSocketConsumer.h" -#include "nsNSSShutDown.h" - -namespace mozilla { -namespace ipc { - -enum ResponseCode { - SUCCESS = 1, - LOCKED = 2, - UNINITIALIZED = 3, - SYSTEM_ERROR = 4, - PROTOCOL_ERROR = 5, - PERMISSION_DENIED = 6, - KEY_NOT_FOUND = 7, - VALUE_CORRUPTED = 8, - UNDEFINED_ACTION = 9, - WRONG_PASSWORD_0 = 10, - WRONG_PASSWORD_1 = 11, - WRONG_PASSWORD_2 = 12, - WRONG_PASSWORD_3 = 13, // MAX_RETRY = 4 - NO_RESPONSE -}; - -void FormatCaData(const uint8_t *aCaData, int aCaDataLength, - const char *aName, const uint8_t **aFormatData, - size_t *aFormatDataLength); - -ResponseCode getCertificate(const char *aCertName, const uint8_t **aCertData, - size_t *aCertDataLength); -ResponseCode getPrivateKey(const char *aKeyName, const uint8_t **aKeyData, - size_t *aKeyDataLength); -ResponseCode getPublicKey(const char *aKeyName, const uint8_t **aKeyData, - size_t *aKeyDataLength); -ResponseCode signData(const char *aKeyName, const uint8_t *data, size_t length, - uint8_t **out, size_t *outLength); - -bool checkPermission(uid_t uid); - -static const int MAX_PARAM = 2; -static const int KEY_SIZE = ((NAME_MAX - 15) / 2); -static const int VALUE_SIZE = 32768; -static const int PASSWORD_SIZE = VALUE_SIZE; - -static const int CA_LINE_SIZE = 64; - -struct ProtocolCommand { - int8_t command; - int paramNum; -}; - -static const struct ProtocolCommand commands[] = { - {'g', 1}, // Get CA, command "g CERT_NAME" - { 0, 0} -}; - -struct ProtocolParam{ - uint length; - int8_t data[VALUE_SIZE]; -}; - -typedef enum { - STATE_IDLE, - STATE_READ_PARAM_LEN, - STATE_READ_PARAM_DATA, - STATE_PROCESSING -} ProtocolHandlerState; - -class KeyStore final - : public StreamSocketConsumer - , public ListenSocketConsumer - , public nsNSSShutDownObject -{ -public: - NS_INLINE_DECL_THREADSAFE_REFCOUNTING(KeyStore) - - KeyStore(); - - void Shutdown(); - -protected: - virtual void virtualDestroyNSSReference() {} - -private: - enum SocketType { - LISTEN_SOCKET, - STREAM_SOCKET - }; - - ~KeyStore(); - - struct { - ProtocolHandlerState state; - uint8_t command; - struct ProtocolParam param[MAX_PARAM]; - int paramCount; - const struct ProtocolCommand *commandPattern; - } mHandlerInfo; - void ResetHandlerInfo(); - void Listen(); - - bool CheckSize(UnixSocketBuffer *aMessage, size_t aExpectSize); - ResponseCode ReadCommand(UnixSocketBuffer *aMessage); - ResponseCode ReadLength(UnixSocketBuffer *aMessage); - ResponseCode ReadData(UnixSocketBuffer *aMessage); - void SendResponse(ResponseCode response); - void SendData(const uint8_t *data, int length); - - // Methods for |StreamSocketConsumer| - // - - void ReceiveSocketData(int aIndex, - UniquePtr<UnixSocketBuffer>& aMessage) override; - void OnConnectSuccess(int aIndex) override; - void OnConnectError(int aIndex) override; - void OnDisconnect(int aIndex) override; - - bool mShutdown; - - RefPtr<ListenSocket> mListenSocket; - RefPtr<StreamSocket> mStreamSocket; -}; - -} // namespace ipc -} // namespace mozilla - -#endif // mozilla_ipc_KeyStore_h diff --git a/ipc/keystore/KeyStoreConnector.cpp b/ipc/keystore/KeyStoreConnector.cpp deleted file mode 100644 index 0e11fcec6..000000000 --- a/ipc/keystore/KeyStoreConnector.cpp +++ /dev/null @@ -1,239 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set sw=2 ts=2 et ft=cpp: 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 "KeyStoreConnector.h" -#include <fcntl.h> -#include <pwd.h> -#include <sys/stat.h> -#include <sys/un.h> -#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, MOZ_COUNT_DTOR -#include "nsThreadUtils.h" // For NS_IsMainThread. - -#ifdef MOZ_WIDGET_GONK -#include <android/log.h> -#define KEYSTORE_LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gonk", args) -#else -#define KEYSTORE_LOG(args...) printf(args); -#endif - -namespace mozilla { -namespace ipc { - -static const char KEYSTORE_SOCKET_PATH[] = "/dev/socket/keystore"; - -KeyStoreConnector::KeyStoreConnector(const char** const aAllowedUsers) - : mAllowedUsers(aAllowedUsers) -{ - MOZ_COUNT_CTOR_INHERITED(KeyStoreConnector, UnixSocketConnector); -} - -KeyStoreConnector::~KeyStoreConnector() -{ - MOZ_COUNT_DTOR_INHERITED(KeyStoreConnector, UnixSocketConnector); -} - -nsresult -KeyStoreConnector::CreateSocket(int& aFd) const -{ - unlink(KEYSTORE_SOCKET_PATH); - - aFd = socket(AF_LOCAL, SOCK_STREAM, 0); - if (aFd < 0) { - KEYSTORE_LOG("Could not open KeyStore socket!"); - return NS_ERROR_FAILURE; - } - - return NS_OK; -} - -nsresult -KeyStoreConnector::SetSocketFlags(int aFd) const -{ - static const int sReuseAddress = 1; - - // Set close-on-exec bit. - int flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFD)); - if (flags < 0) { - return NS_ERROR_FAILURE; - } - flags |= FD_CLOEXEC; - int res = TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFD, flags)); - if (res < 0) { - return NS_ERROR_FAILURE; - } - - // Set non-blocking status flag. - flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFL)); - if (flags < 0) { - return NS_ERROR_FAILURE; - } - flags |= O_NONBLOCK; - res = TEMP_FAILURE_RETRY(fcntl(aFd, F_SETFL, flags)); - if (res < 0) { - return NS_ERROR_FAILURE; - } - - // Set socket addr to be reused even if kernel is still waiting to close. - res = setsockopt(aFd, SOL_SOCKET, SO_REUSEADDR, &sReuseAddress, - sizeof(sReuseAddress)); - if (res < 0) { - return NS_ERROR_FAILURE; - } - - return NS_OK; -} - -nsresult -KeyStoreConnector::CheckPermission(int aFd) const -{ - struct ucred userCred; - socklen_t len = sizeof(userCred); - - if (getsockopt(aFd, SOL_SOCKET, SO_PEERCRED, &userCred, &len)) { - return NS_ERROR_FAILURE; - } - - const struct passwd* userInfo = getpwuid(userCred.uid); - if (!userInfo) { - return NS_ERROR_FAILURE; - } - - if (!mAllowedUsers) { - return NS_ERROR_FAILURE; - } - - for (const char** user = mAllowedUsers; *user; ++user) { - if (!strcmp(*user, userInfo->pw_name)) { - return NS_OK; - } - } - - return NS_ERROR_FAILURE; -} - -nsresult -KeyStoreConnector::CreateAddress(struct sockaddr& aAddress, - socklen_t& aAddressLength) const -{ - struct sockaddr_un* address = - reinterpret_cast<struct sockaddr_un*>(&aAddress); - - size_t namesiz = strlen(KEYSTORE_SOCKET_PATH) + 1; // include trailing '\0' - - if (namesiz > sizeof(address->sun_path)) { - KEYSTORE_LOG("Address too long for socket struct!"); - return NS_ERROR_FAILURE; - } - - address->sun_family = AF_UNIX; - memcpy(address->sun_path, KEYSTORE_SOCKET_PATH, namesiz); - - aAddressLength = offsetof(struct sockaddr_un, sun_path) + namesiz; - - return NS_OK; -} - -// |UnixSocketConnector| - -nsresult -KeyStoreConnector::ConvertAddressToString(const struct sockaddr& aAddress, - socklen_t aAddressLength, - nsACString& aAddressString) -{ - MOZ_ASSERT(aAddress.sa_family == AF_UNIX); - - const struct sockaddr_un* un = - reinterpret_cast<const struct sockaddr_un*>(&aAddress); - - size_t len = aAddressLength - offsetof(struct sockaddr_un, sun_path); - - aAddressString.Assign(un->sun_path, len); - - return NS_OK; -} - -nsresult -KeyStoreConnector::CreateListenSocket(struct sockaddr* aAddress, - socklen_t* aAddressLength, - int& aListenFd) -{ - ScopedClose fd; - - nsresult rv = CreateSocket(fd.rwget()); - if (NS_FAILED(rv)) { - return rv; - } - rv = SetSocketFlags(fd); - if (NS_FAILED(rv)) { - return rv; - } - if (aAddress && aAddressLength) { - rv = CreateAddress(*aAddress, *aAddressLength); - if (NS_FAILED(rv)) { - return rv; - } - } - - // Allow access for wpa_supplicant (different user, different group) - // - // TODO: Improve this by setting specific user/group for - // wpa_supplicant by calling |fchmod| and |fchown|. - // - chmod(KEYSTORE_SOCKET_PATH, S_IRUSR|S_IWUSR| - S_IRGRP|S_IWGRP| - S_IROTH|S_IWOTH); - - aListenFd = fd.forget(); - - return NS_OK; -} - -nsresult -KeyStoreConnector::AcceptStreamSocket(int aListenFd, - struct sockaddr* aAddress, - socklen_t* aAddressLength, - int& aStreamFd) -{ - ScopedClose fd( - TEMP_FAILURE_RETRY(accept(aListenFd, aAddress, aAddressLength))); - if (fd < 0) { - NS_WARNING("Cannot accept file descriptor!"); - return NS_ERROR_FAILURE; - } - nsresult rv = SetSocketFlags(fd); - if (NS_FAILED(rv)) { - return rv; - } - rv = CheckPermission(fd); - if (NS_FAILED(rv)) { - return rv; - } - - aStreamFd = fd.forget(); - - return NS_OK; -} - -nsresult -KeyStoreConnector::CreateStreamSocket(struct sockaddr* aAddress, - socklen_t* aAddressLength, - int& aStreamFd) -{ - MOZ_CRASH("|KeyStoreConnector| does not support creating stream sockets."); - return NS_ERROR_FAILURE; -} - -nsresult -KeyStoreConnector::Duplicate(UnixSocketConnector*& aConnector) -{ - aConnector = new KeyStoreConnector(*this); - - return NS_OK; -} - -} -} diff --git a/ipc/keystore/KeyStoreConnector.h b/ipc/keystore/KeyStoreConnector.h deleted file mode 100644 index 349b030de..000000000 --- a/ipc/keystore/KeyStoreConnector.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set sw=2 ts=2 et ft=cpp: 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/. */ - -#ifndef mozilla_ipc_KeyStoreConnector_h -#define mozilla_ipc_KeyStoreConnector_h - -#include "mozilla/ipc/UnixSocketConnector.h" - -namespace mozilla { -namespace ipc { - -class KeyStoreConnector final : public UnixSocketConnector -{ -public: - KeyStoreConnector(const char** const aAllowedUsers); - ~KeyStoreConnector(); - - // Methods for |UnixSocketConnector| - // - - nsresult ConvertAddressToString(const struct sockaddr& aAddress, - socklen_t aAddressLength, - nsACString& aAddressString) override; - - nsresult CreateListenSocket(struct sockaddr* aAddress, - socklen_t* aAddressLength, - int& aListenFd) override; - - nsresult AcceptStreamSocket(int aListenFd, - struct sockaddr* aAddress, - socklen_t* aAddressLength, - int& aStreamFd) override; - - nsresult CreateStreamSocket(struct sockaddr* aAddress, - socklen_t* aAddressLength, - int& aStreamFd) override; - - nsresult Duplicate(UnixSocketConnector*& aConnector) override; - -private: - nsresult CreateSocket(int& aFd) const; - nsresult SetSocketFlags(int aFd) const; - nsresult CheckPermission(int aFd) const; - nsresult CreateAddress(struct sockaddr& aAddress, - socklen_t& aAddressLength) const; - - const char** const mAllowedUsers; -}; - -} -} - -#endif diff --git a/ipc/keystore/moz.build b/ipc/keystore/moz.build deleted file mode 100644 index e5df10a30..000000000 --- a/ipc/keystore/moz.build +++ /dev/null @@ -1,18 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# 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/. - -EXPORTS.mozilla.ipc += [ - 'KeyStore.h' -] - -SOURCES += [ - 'KeyStore.cpp', - 'KeyStoreConnector.cpp' -] - -include('/ipc/chromium/chromium-config.mozbuild') - -FINAL_LIBRARY = 'xul' diff --git a/ipc/moz.build b/ipc/moz.build index d01b7bbed..320d8c5f0 100644 --- a/ipc/moz.build +++ b/ipc/moz.build @@ -14,12 +14,6 @@ DIRS += [ if CONFIG['MOZ_ENABLE_DBUS']: DIRS += ['dbus'] -if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': - DIRS += ['unixfd', 'unixsocket'] - -if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': - DIRS += ['hal', 'keystore', 'netd'] - if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'android': DIRS += ['contentproc'] diff --git a/ipc/mscom/InterceptorLog.cpp b/ipc/mscom/InterceptorLog.cpp index c2cd3c7df..3f3dc3f34 100644 --- a/ipc/mscom/InterceptorLog.cpp +++ b/ipc/mscom/InterceptorLog.cpp @@ -98,13 +98,8 @@ Logger::Logger(const nsACString& aLeafBaseName) rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(logFileName)); } else if (procType == GeckoProcessType_Content) { leafName.AppendLiteral("-Content-"); -#if defined(MOZ_CONTENT_SANDBOX) - rv = NS_GetSpecialDirectory(NS_APP_CONTENT_PROCESS_TEMP_DIR, - getter_AddRefs(logFileName)); -#else rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(logFileName)); -#endif // defined(MOZ_CONTENT_SANDBOX) } else { return; } diff --git a/ipc/netd/Netd.cpp b/ipc/netd/Netd.cpp deleted file mode 100644 index 99350f250..000000000 --- a/ipc/netd/Netd.cpp +++ /dev/null @@ -1,374 +0,0 @@ -/* 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 "Netd.h" -#include <android/log.h> -#include <cutils/sockets.h> -#include <fcntl.h> -#include <sys/socket.h> - -#include "android/log.h" -#include "base/task.h" - -#include "nsWhitespaceTokenizer.h" -#include "nsXULAppAPI.h" -#include "nsString.h" -#include "nsThreadUtils.h" -#include "mozilla/RefPtr.h" -#include "mozilla/Sprintf.h" -#include "SystemProperty.h" - -#define NETD_LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gonk", args) -#define ICS_SYS_USB_RNDIS_MAC "/sys/class/android_usb/android0/f_rndis/ethaddr" -#define INVALID_SOCKET -1 -#define MAX_RECONNECT_TIMES 10 - -using mozilla::system::Property; - -namespace { - -RefPtr<mozilla::ipc::NetdClient> gNetdClient; -RefPtr<mozilla::ipc::NetdConsumer> gNetdConsumer; - -class StopNetdConsumer : public mozilla::Runnable { -public: - NS_IMETHOD Run() override - { - MOZ_ASSERT(NS_IsMainThread()); - - gNetdConsumer = nullptr; - return NS_OK; - } -}; - -bool -InitRndisAddress() -{ - char mac[20]; - char serialno[] = "1234567890ABCDEF"; - static const int kEthernetAddressLength = 6; - char address[kEthernetAddressLength]; - int i = 0; - int ret = 0; - int length = 0; - mozilla::ScopedClose fd; - - fd.rwget() = open(ICS_SYS_USB_RNDIS_MAC, O_WRONLY); - if (fd.rwget() == -1) { - NETD_LOG("Unable to open file %s.", ICS_SYS_USB_RNDIS_MAC); - return false; - } - - Property::Get("ro.serialno", serialno, "1234567890ABCDEF"); - - memset(address, 0, sizeof(address)); - // First byte is 0x02 to signify a locally administered address. - address[0] = 0x02; - length = strlen(serialno); - for (i = 0; i < length; i++) { - address[i % (kEthernetAddressLength - 1) + 1] ^= serialno[i]; - } - - SprintfLiteral(mac, "%02x:%02x:%02x:%02x:%02x:%02x", - address[0], address[1], address[2], - address[3], address[4], address[5]); - length = strlen(mac); - ret = write(fd.get(), mac, length); - if (ret != length) { - NETD_LOG("Fail to write file %s.", ICS_SYS_USB_RNDIS_MAC); - return false; - } - return true; -} - -} // namespace - -namespace mozilla { -namespace ipc { - -NetdClient::NetdClient() - : LineWatcher('\0', MAX_COMMAND_SIZE) - , mIOLoop(MessageLoopForIO::current()) - , mSocket(INVALID_SOCKET) - , mCurrentWriteOffset(0) - , mReConnectTimes(0) -{ - MOZ_COUNT_CTOR(NetdClient); -} - -NetdClient::~NetdClient() -{ - MOZ_COUNT_DTOR(NetdClient); -} - -bool -NetdClient::OpenSocket() -{ - mSocket.rwget() = socket_local_client("netd", - ANDROID_SOCKET_NAMESPACE_RESERVED, - SOCK_STREAM); - if (mSocket.rwget() < 0) { - NETD_LOG("Error connecting to : netd (%s) - will retry", strerror(errno)); - return false; - } - // Add FD_CLOEXEC flag. - int flags = fcntl(mSocket.get(), F_GETFD); - if (flags == -1) { - NETD_LOG("Error doing fcntl with F_GETFD command(%s)", strerror(errno)); - return false; - } - flags |= FD_CLOEXEC; - if (fcntl(mSocket.get(), F_SETFD, flags) == -1) { - NETD_LOG("Error doing fcntl with F_SETFD command(%s)", strerror(errno)); - return false; - } - // Set non-blocking. - if (fcntl(mSocket.get(), F_SETFL, O_NONBLOCK) == -1) { - NETD_LOG("Error set non-blocking socket(%s)", strerror(errno)); - return false; - } - if (!MessageLoopForIO::current()-> - WatchFileDescriptor(mSocket.get(), - true, - MessageLoopForIO::WATCH_READ, - &mReadWatcher, - this)) { - NETD_LOG("Error set socket read watcher(%s)", strerror(errno)); - return false; - } - - if (!mOutgoingQ.empty()) { - MessageLoopForIO::current()-> - WatchFileDescriptor(mSocket.get(), - false, - MessageLoopForIO::WATCH_WRITE, - &mWriteWatcher, - this); - } - - NETD_LOG("Connected to netd"); - return true; -} - -void NetdClient::OnLineRead(int aFd, nsDependentCSubstring& aMessage) -{ - // Set errno to 0 first. For preventing to use the stale version of errno. - errno = 0; - // We found a line terminator. Each line is formatted as an - // integer response code followed by the rest of the line. - // Fish out the response code. - int responseCode = strtol(aMessage.Data(), nullptr, 10); - if (!errno) { - NetdCommand* response = new NetdCommand(); - // Passing all the response message, including the line terminator. - response->mSize = aMessage.Length(); - memcpy(response->mData, aMessage.Data(), aMessage.Length()); - gNetdConsumer->MessageReceived(response); - } - - if (!responseCode) { - NETD_LOG("Can't parse netd's response"); - } -} - -void -NetdClient::OnFileCanWriteWithoutBlocking(int aFd) -{ - MOZ_ASSERT(aFd == mSocket.get()); - WriteNetdCommand(); -} - -void -NetdClient::OnError() -{ - MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop()); - - mReadWatcher.StopWatchingFileDescriptor(); - mWriteWatcher.StopWatchingFileDescriptor(); - - mSocket.dispose(); - mCurrentWriteOffset = 0; - mCurrentNetdCommand = nullptr; - while (!mOutgoingQ.empty()) { - delete mOutgoingQ.front(); - mOutgoingQ.pop(); - } - Start(); -} - -// static -void -NetdClient::Start() -{ - MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop()); - - if (!gNetdClient) { - NETD_LOG("Netd Client is not initialized"); - return; - } - - if (!gNetdClient->OpenSocket()) { - // Socket open failed, try again in a second. - NETD_LOG("Fail to connect to Netd"); - if (++gNetdClient->mReConnectTimes > MAX_RECONNECT_TIMES) { - NETD_LOG("Fail to connect to Netd after retry %d times", MAX_RECONNECT_TIMES); - return; - } - - MessageLoopForIO::current()-> - PostDelayedTask(NewRunnableFunction(NetdClient::Start), - 1000); - return; - } - gNetdClient->mReConnectTimes = 0; -} - -// static -void -NetdClient::SendNetdCommandIOThread(NetdCommand* aMessage) -{ - MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop()); - MOZ_ASSERT(aMessage); - - if (!gNetdClient) { - NETD_LOG("Netd Client is not initialized"); - return; - } - - gNetdClient->mOutgoingQ.push(aMessage); - - if (gNetdClient->mSocket.get() == INVALID_SOCKET) { - NETD_LOG("Netd connection is not established, push the message to queue"); - return; - } - - gNetdClient->WriteNetdCommand(); -} - -void -NetdClient::WriteNetdCommand() -{ - if (!mCurrentNetdCommand) { - mCurrentWriteOffset = 0; - mCurrentNetdCommand = mOutgoingQ.front(); - mOutgoingQ.pop(); - } - - while (mCurrentWriteOffset < mCurrentNetdCommand->mSize) { - ssize_t write_amount = mCurrentNetdCommand->mSize - mCurrentWriteOffset; - ssize_t written = write(mSocket.get(), - mCurrentNetdCommand->mData + mCurrentWriteOffset, - write_amount); - if (written < 0) { - NETD_LOG("Cannot write to network, error %d\n", (int) written); - OnError(); - return; - } - - if (written > 0) { - mCurrentWriteOffset += written; - } - - if (written != write_amount) { - NETD_LOG("WriteNetdCommand fail !!! Write is not completed"); - break; - } - } - - if (mCurrentWriteOffset != mCurrentNetdCommand->mSize) { - MessageLoopForIO::current()-> - WatchFileDescriptor(mSocket.get(), - false, - MessageLoopForIO::WATCH_WRITE, - &mWriteWatcher, - this); - return; - } - - mCurrentNetdCommand = nullptr; -} - -static void -InitNetdIOThread() -{ - bool result; - char propValue[Property::VALUE_MAX_LENGTH]; - - MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop()); - MOZ_ASSERT(!gNetdClient); - - Property::Get("ro.build.version.sdk", propValue, "0"); - // Assign rndis address for usb tethering in ICS. - if (atoi(propValue) >= 15) { - result = InitRndisAddress(); - // We don't return here because InitRnsisAddress() function is related to - // usb tethering only. Others service such as wifi tethering still need - // to use ipc to communicate with netd. - if (!result) { - NETD_LOG("fail to give rndis interface an address"); - } - } - gNetdClient = new NetdClient(); - gNetdClient->Start(); -} - -static void -ShutdownNetdIOThread() -{ - MOZ_ASSERT(MessageLoop::current() == XRE_GetIOMessageLoop()); - nsCOMPtr<nsIRunnable> shutdownEvent = new StopNetdConsumer(); - - gNetdClient = nullptr; - - NS_DispatchToMainThread(shutdownEvent); -} - -void -StartNetd(NetdConsumer* aNetdConsumer) -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(aNetdConsumer); - MOZ_ASSERT(gNetdConsumer == nullptr); - - gNetdConsumer = aNetdConsumer; - XRE_GetIOMessageLoop()->PostTask( - NewRunnableFunction(InitNetdIOThread)); -} - -void -StopNetd() -{ - MOZ_ASSERT(NS_IsMainThread()); - - nsIThread* currentThread = NS_GetCurrentThread(); - NS_ASSERTION(currentThread, "This should never be null!"); - - XRE_GetIOMessageLoop()->PostTask( - NewRunnableFunction(ShutdownNetdIOThread)); - - while (gNetdConsumer) { - if (!NS_ProcessNextEvent(currentThread)) { - NS_WARNING("Something bad happened!"); - break; - } - } -} - -/************************************************************************** -* -* This function runs in net worker Thread context. The net worker thread -* is created in dom/system/gonk/NetworkManager.js -* -**************************************************************************/ -void -SendNetdCommand(NetdCommand* aMessage) -{ - MOZ_ASSERT(aMessage); - - XRE_GetIOMessageLoop()->PostTask( - NewRunnableFunction(NetdClient::SendNetdCommandIOThread, aMessage)); -} - -} // namespace ipc -} // namespace mozilla diff --git a/ipc/netd/Netd.h b/ipc/netd/Netd.h deleted file mode 100644 index e4e20d2a8..000000000 --- a/ipc/netd/Netd.h +++ /dev/null @@ -1,81 +0,0 @@ -/* 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/. */ - -#ifndef mozilla_system_netd_h__ -#define mozilla_system_netd_h__ - -#include "nsISupportsImpl.h" -#include "nsAutoPtr.h" -#include "base/message_loop.h" -#include "mozilla/FileUtils.h" - -#define MAX_COMMAND_SIZE 4096 - -namespace mozilla { -namespace ipc { - -/* - * Represents raw data going to or coming from the Netd socket. - */ -struct NetdCommand -{ - uint8_t mData[MAX_COMMAND_SIZE]; - - // Number of octets in mData. - size_t mSize; -}; - -class NetdConsumer -{ -protected: - virtual ~NetdConsumer() { } - -public: - NS_INLINE_DECL_REFCOUNTING(NetdConsumer) - - virtual void MessageReceived(NetdCommand* aMessage) = 0; -}; - -class NetdWriteTask : public Runnable -{ - NS_IMETHOD Run(); -}; - -class NetdClient : public MessageLoopForIO::LineWatcher -{ - virtual ~NetdClient(); - -public: - NS_INLINE_DECL_REFCOUNTING(NetdClient) - typedef std::queue<NetdCommand*> NetdCommandQueue; - - NetdClient(); - static void Start(); - static void SendNetdCommandIOThread(NetdCommand* aMessage); - -private: - void WriteNetdCommand(); - virtual void OnError(); - virtual void OnLineRead(int aFd, nsDependentCSubstring& aMessage); - virtual void OnFileCanWriteWithoutBlocking(int aFd); - bool OpenSocket(); - - MessageLoopForIO *mIOLoop; - MessageLoopForIO::FileDescriptorWatcher mReadWatcher; - MessageLoopForIO::FileDescriptorWatcher mWriteWatcher; - ScopedClose mSocket; - NetdCommandQueue mOutgoingQ; - nsAutoPtr<NetdCommand> mCurrentNetdCommand; - size_t mCurrentWriteOffset; - size_t mReConnectTimes; -}; - -void StartNetd(NetdConsumer *); -void StopNetd(); -void SendNetdCommand(NetdCommand *); - -} // namespace ipc -} // namespace mozilla - -#endif // mozilla_system_netd_h__ diff --git a/ipc/netd/moz.build b/ipc/netd/moz.build deleted file mode 100644 index 23340cb93..000000000 --- a/ipc/netd/moz.build +++ /dev/null @@ -1,17 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# 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/. - -EXPORTS.mozilla.ipc += [ - 'Netd.h', -] - -SOURCES += [ - 'Netd.cpp', -] - -include('/ipc/chromium/chromium-config.mozbuild') - -FINAL_LIBRARY = 'xul' diff --git a/ipc/ril/Ril.cpp b/ipc/ril/Ril.cpp index 90fb12052..5c48643cc 100644 --- a/ipc/ril/Ril.cpp +++ b/ipc/ril/Ril.cpp @@ -21,12 +21,7 @@ #undef CHROMIUM_LOG #endif -#if defined(MOZ_WIDGET_GONK) -#include <android/log.h> -#define CHROMIUM_LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gonk", args) -#else #define CHROMIUM_LOG(args...) printf(args); -#endif namespace mozilla { namespace ipc { diff --git a/ipc/ril/RilConnector.cpp b/ipc/ril/RilConnector.cpp index 6e10beed7..7a86befaa 100644 --- a/ipc/ril/RilConnector.cpp +++ b/ipc/ril/RilConnector.cpp @@ -181,11 +181,7 @@ RilConnector::CreateStreamSocket(struct sockaddr* aAddress, socklen_t* aAddressLength, int& aStreamFd) { -#ifdef MOZ_WIDGET_GONK - static const int sDomain = AF_UNIX; -#else static const int sDomain = AF_INET; -#endif ScopedClose fd; diff --git a/ipc/unixfd/UnixFdWatcher.cpp b/ipc/unixfd/UnixFdWatcher.cpp deleted file mode 100644 index 41289a90b..000000000 --- a/ipc/unixfd/UnixFdWatcher.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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 <fcntl.h> -#include "UnixFdWatcher.h" - -#ifdef CHROMIUM_LOG -#undef CHROMIUM_LOG -#endif - -#if defined(MOZ_WIDGET_GONK) -#include <android/log.h> -#define CHROMIUM_LOG(args...) __android_log_print(ANDROID_LOG_INFO, "I/O", args); -#else -#include <stdio.h> -#define IODEBUG true -#define CHROMIUM_LOG(args...) if (IODEBUG) printf(args); -#endif - -namespace mozilla { -namespace ipc { - -UnixFdWatcher::~UnixFdWatcher() -{ - NS_WARNING_ASSERTION(!IsOpen(), "mFd should have been closed already"); -} - -void -UnixFdWatcher::Close() -{ - MOZ_ASSERT(MessageLoopForIO::current() == mIOLoop); - - if (NS_WARN_IF(!IsOpen())) { - /* mFd should have been open */ - return; - } - OnClose(); - RemoveWatchers(READ_WATCHER|WRITE_WATCHER); - mFd.dispose(); -} - -void -UnixFdWatcher::AddWatchers(unsigned long aWatchers, bool aPersistent) -{ - MOZ_ASSERT(MessageLoopForIO::current() == mIOLoop); - MOZ_ASSERT(IsOpen()); - - // Before we add a watcher, we need to remove it! Removing is always - // safe, but adding the same watcher twice can lead to endless loops - // inside libevent. - RemoveWatchers(aWatchers); - - if (aWatchers & READ_WATCHER) { - MessageLoopForIO::current()->WatchFileDescriptor( - mFd, - aPersistent, - MessageLoopForIO::WATCH_READ, - &mReadWatcher, - this); - } - if (aWatchers & WRITE_WATCHER) { - MessageLoopForIO::current()->WatchFileDescriptor( - mFd, - aPersistent, - MessageLoopForIO::WATCH_WRITE, - &mWriteWatcher, - this); - } -} - -void -UnixFdWatcher::RemoveWatchers(unsigned long aWatchers) -{ - MOZ_ASSERT(MessageLoopForIO::current() == mIOLoop); - MOZ_ASSERT(IsOpen()); - - if (aWatchers & READ_WATCHER) { - mReadWatcher.StopWatchingFileDescriptor(); - } - if (aWatchers & WRITE_WATCHER) { - mWriteWatcher.StopWatchingFileDescriptor(); - } -} - -void -UnixFdWatcher::OnError(const char* aFunction, int aErrno) -{ - MOZ_ASSERT(MessageLoopForIO::current() == mIOLoop); - - CHROMIUM_LOG("%s failed with error %d (%s)", - aFunction, aErrno, strerror(aErrno)); -} - -UnixFdWatcher::UnixFdWatcher(MessageLoop* aIOLoop) -: mIOLoop(aIOLoop) -{ - MOZ_ASSERT(mIOLoop); -} - -UnixFdWatcher::UnixFdWatcher(MessageLoop* aIOLoop, int aFd) -: mIOLoop(aIOLoop) -, mFd(aFd) -{ - MOZ_ASSERT(mIOLoop); -} - -void -UnixFdWatcher::SetFd(int aFd) -{ - MOZ_ASSERT(MessageLoopForIO::current() == mIOLoop); - MOZ_ASSERT(!IsOpen()); - MOZ_ASSERT(FdIsNonBlocking(aFd)); - - mFd = aFd; -} - -bool -UnixFdWatcher::FdIsNonBlocking(int aFd) -{ - int flags = TEMP_FAILURE_RETRY(fcntl(aFd, F_GETFL)); - return (flags > 0) && (flags & O_NONBLOCK); -} - -} -} diff --git a/ipc/unixfd/UnixFdWatcher.h b/ipc/unixfd/UnixFdWatcher.h deleted file mode 100644 index 676b1dbf0..000000000 --- a/ipc/unixfd/UnixFdWatcher.h +++ /dev/null @@ -1,69 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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/. */ - -#ifndef mozilla_ipc_UnixFdWatcher_h -#define mozilla_ipc_UnixFdWatcher_h - -#include "base/message_loop.h" -#include "mozilla/FileUtils.h" - -namespace mozilla { -namespace ipc { - -class UnixFdWatcher : public MessageLoopForIO::Watcher -{ -public: - enum { - READ_WATCHER = 1<<0, - WRITE_WATCHER = 1<<1 - }; - - virtual ~UnixFdWatcher(); - - MessageLoop* GetIOLoop() const - { - return mIOLoop; - } - - int GetFd() const - { - return mFd; - } - - bool IsOpen() const - { - return GetFd() >= 0; - } - - virtual void Close(); - - void AddWatchers(unsigned long aWatchers, bool aPersistent); - void RemoveWatchers(unsigned long aWatchers); - - // Callback method that's run before closing the file descriptor - virtual void OnClose() {}; - - // Callback method that's run on POSIX errors - virtual void OnError(const char* aFunction, int aErrno); - -protected: - UnixFdWatcher(MessageLoop* aIOLoop); - UnixFdWatcher(MessageLoop* aIOLoop, int aFd); - void SetFd(int aFd); - -private: - static bool FdIsNonBlocking(int aFd); - - MessageLoop* mIOLoop; - ScopedClose mFd; - MessageLoopForIO::FileDescriptorWatcher mReadWatcher; - MessageLoopForIO::FileDescriptorWatcher mWriteWatcher; -}; - -} -} - -#endif diff --git a/ipc/unixfd/UnixFileWatcher.cpp b/ipc/unixfd/UnixFileWatcher.cpp deleted file mode 100644 index 67e247b5b..000000000 --- a/ipc/unixfd/UnixFileWatcher.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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 <fcntl.h> -#include "UnixFileWatcher.h" - -namespace mozilla { -namespace ipc { - -UnixFileWatcher::~UnixFileWatcher() -{ -} - -nsresult -UnixFileWatcher::Open(const char* aFilename, int aFlags, mode_t aMode) -{ - MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); - MOZ_ASSERT(aFlags & O_NONBLOCK); - - int fd = TEMP_FAILURE_RETRY(open(aFilename, aFlags, aMode)); - if (fd < 0) { - OnError("open", errno); - return NS_ERROR_FAILURE; - } - SetFd(fd); - OnOpened(); - - return NS_OK; -} - -UnixFileWatcher::UnixFileWatcher(MessageLoop* aIOLoop) -: UnixFdWatcher(aIOLoop) -{ -} - -UnixFileWatcher::UnixFileWatcher(MessageLoop* aIOLoop, int aFd) -: UnixFdWatcher(aIOLoop, aFd) -{ -} - -} -} diff --git a/ipc/unixfd/UnixFileWatcher.h b/ipc/unixfd/UnixFileWatcher.h deleted file mode 100644 index 5a19b1005..000000000 --- a/ipc/unixfd/UnixFileWatcher.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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/. */ - -#ifndef mozilla_ipc_UnixFileWatcher_h -#define mozilla_ipc_UnixFileWatcher_h - -#include "UnixFdWatcher.h" - -namespace mozilla { -namespace ipc { - -class UnixFileWatcher : public UnixFdWatcher -{ -public: - virtual ~UnixFileWatcher(); - - nsresult Open(const char* aFilename, int aFlags, mode_t aMode = 0); - - // Callback method for successful open requests - virtual void OnOpened() {}; - -protected: - UnixFileWatcher(MessageLoop* aIOLoop); - UnixFileWatcher(MessageLoop* aIOLoop, int aFd); -}; - -} -} - -#endif diff --git a/ipc/unixfd/UnixSocketWatcher.cpp b/ipc/unixfd/UnixSocketWatcher.cpp deleted file mode 100644 index 2ce32e93d..000000000 --- a/ipc/unixfd/UnixSocketWatcher.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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 <fcntl.h> -#include "UnixSocketWatcher.h" - -namespace mozilla { -namespace ipc { - -UnixSocketWatcher::~UnixSocketWatcher() -{ -} - -void UnixSocketWatcher::Close() -{ - MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); - - mConnectionStatus = SOCKET_IS_DISCONNECTED; - UnixFdWatcher::Close(); -} - -nsresult -UnixSocketWatcher::Connect(const struct sockaddr* aAddr, socklen_t aAddrLen) -{ - MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); - MOZ_ASSERT(IsOpen()); - MOZ_ASSERT(aAddr || !aAddrLen); - - if (TEMP_FAILURE_RETRY(connect(GetFd(), aAddr, aAddrLen) < 0)) { - if (errno == EINPROGRESS) { - mConnectionStatus = SOCKET_IS_CONNECTING; - // Set up a write watch to receive the connect signal - AddWatchers(WRITE_WATCHER, false); - return NS_OK; - } - OnError("connect", errno); - return NS_ERROR_FAILURE; - } - - mConnectionStatus = SOCKET_IS_CONNECTED; - OnConnected(); - - return NS_OK; -} - -nsresult -UnixSocketWatcher::Listen(const struct sockaddr* aAddr, socklen_t aAddrLen) -{ - MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); - MOZ_ASSERT(IsOpen()); - MOZ_ASSERT(aAddr || !aAddrLen); - - if (mConnectionStatus == SOCKET_IS_DISCONNECTED) { - // We init the socket descriptor when we listen for the first time. - if (bind(GetFd(), aAddr, aAddrLen) < 0) { - OnError("bind", errno); - return NS_ERROR_FAILURE; - } - if (listen(GetFd(), 1) < 0) { - OnError("listen", errno); - return NS_ERROR_FAILURE; - } - } - mConnectionStatus = SOCKET_IS_LISTENING; - OnListening(); - - return NS_OK; -} - -UnixSocketWatcher::UnixSocketWatcher(MessageLoop* aIOLoop) -: UnixFdWatcher(aIOLoop) -, mConnectionStatus(SOCKET_IS_DISCONNECTED) -{ -} - -UnixSocketWatcher::UnixSocketWatcher(MessageLoop* aIOLoop, int aFd, - ConnectionStatus aConnectionStatus) -: UnixFdWatcher(aIOLoop, aFd) -, mConnectionStatus(aConnectionStatus) -{ -} - -void -UnixSocketWatcher::SetSocket(int aFd, ConnectionStatus aConnectionStatus) -{ - MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); - - SetFd(aFd); - mConnectionStatus = aConnectionStatus; -} - -void -UnixSocketWatcher::OnFileCanReadWithoutBlocking(int aFd) -{ - MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); - MOZ_ASSERT(aFd == GetFd()); - - if (mConnectionStatus == SOCKET_IS_CONNECTED) { - OnSocketCanReceiveWithoutBlocking(); - } else if (mConnectionStatus == SOCKET_IS_LISTENING) { - OnSocketCanAcceptWithoutBlocking(); - } else { - NS_NOTREACHED("invalid connection state for reading"); - } -} - -void -UnixSocketWatcher::OnFileCanWriteWithoutBlocking(int aFd) -{ - MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); - MOZ_ASSERT(aFd == GetFd()); - - if (mConnectionStatus == SOCKET_IS_CONNECTED) { - OnSocketCanSendWithoutBlocking(); - } else if (mConnectionStatus == SOCKET_IS_CONNECTING) { - RemoveWatchers(WRITE_WATCHER); - int error = 0; - socklen_t len = sizeof(error); - if (getsockopt(GetFd(), SOL_SOCKET, SO_ERROR, &error, &len) < 0) { - OnError("getsockopt", errno); - } else if (error) { - OnError("connect", error); - } else { - mConnectionStatus = SOCKET_IS_CONNECTED; - OnConnected(); - } - } else { - NS_NOTREACHED("invalid connection state for writing"); - } -} - -} -} diff --git a/ipc/unixfd/UnixSocketWatcher.h b/ipc/unixfd/UnixSocketWatcher.h deleted file mode 100644 index 37a0acc0d..000000000 --- a/ipc/unixfd/UnixSocketWatcher.h +++ /dev/null @@ -1,72 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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/. */ - -#ifndef mozilla_ipc_UnixSocketWatcher_h -#define mozilla_ipc_UnixSocketWatcher_h - -#include <sys/socket.h> -#include "UnixFdWatcher.h" - -namespace mozilla { -namespace ipc { - -class UnixSocketWatcher : public UnixFdWatcher -{ -public: - enum ConnectionStatus { - SOCKET_IS_DISCONNECTED = 0, - SOCKET_IS_LISTENING, - SOCKET_IS_CONNECTING, - SOCKET_IS_CONNECTED - }; - - virtual ~UnixSocketWatcher(); - - virtual void Close() override; - - ConnectionStatus GetConnectionStatus() const - { - return mConnectionStatus; - } - - // Connect to a peer - nsresult Connect(const struct sockaddr* aAddr, socklen_t aAddrLen); - - // Listen on socket for incoming connection requests - nsresult Listen(const struct sockaddr* aAddr, socklen_t aAddrLen); - - // Callback method for successful connection requests - virtual void OnConnected() {}; - - // Callback method for successful listen requests - virtual void OnListening() {}; - - // Callback method for accepting from a listening socket - virtual void OnSocketCanAcceptWithoutBlocking() {}; - - // Callback method for receiving from socket - virtual void OnSocketCanReceiveWithoutBlocking() {}; - - // Callback method for sending on socket - virtual void OnSocketCanSendWithoutBlocking() {}; - -protected: - UnixSocketWatcher(MessageLoop* aIOLoop); - UnixSocketWatcher(MessageLoop* aIOLoop, int aFd, - ConnectionStatus aConnectionStatus); - void SetSocket(int aFd, ConnectionStatus aConnectionStatus); - -private: - void OnFileCanReadWithoutBlocking(int aFd) override; - void OnFileCanWriteWithoutBlocking(int aFd) override; - - ConnectionStatus mConnectionStatus; -}; - -} -} - -#endif diff --git a/ipc/unixfd/moz.build b/ipc/unixfd/moz.build deleted file mode 100644 index fdc8a8709..000000000 --- a/ipc/unixfd/moz.build +++ /dev/null @@ -1,21 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# 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/. - -EXPORTS.mozilla.ipc += [ - 'UnixFdWatcher.h', - 'UnixFileWatcher.h', - 'UnixSocketWatcher.h' -] - -SOURCES += [ - 'UnixFdWatcher.cpp', - 'UnixFileWatcher.cpp', - 'UnixSocketWatcher.cpp' -] - -include('/ipc/chromium/chromium-config.mozbuild') - -FINAL_LIBRARY = 'xul' diff --git a/ipc/unixsocket/ConnectionOrientedSocket.cpp b/ipc/unixsocket/ConnectionOrientedSocket.cpp deleted file mode 100644 index abcfd1734..000000000 --- a/ipc/unixsocket/ConnectionOrientedSocket.cpp +++ /dev/null @@ -1,202 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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 "ConnectionOrientedSocket.h" -#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, MOZ_COUNT_DTOR -#include "UnixSocketConnector.h" - -namespace mozilla { -namespace ipc { - -// -// ConnectionOrientedSocketIO -// - -ConnectionOrientedSocketIO::ConnectionOrientedSocketIO( - MessageLoop* aConsumerLoop, - MessageLoop* aIOLoop, - int aFd, ConnectionStatus aConnectionStatus, - UnixSocketConnector* aConnector) - : DataSocketIO(aConsumerLoop) - , UnixSocketWatcher(aIOLoop, aFd, aConnectionStatus) - , mConnector(aConnector) - , mPeerAddressLength(0) -{ - MOZ_ASSERT(mConnector); - - MOZ_COUNT_CTOR_INHERITED(ConnectionOrientedSocketIO, DataSocketIO); -} - -ConnectionOrientedSocketIO::ConnectionOrientedSocketIO( - MessageLoop* aConsumerLoop, - MessageLoop* aIOLoop, - UnixSocketConnector* aConnector) - : DataSocketIO(aConsumerLoop) - , UnixSocketWatcher(aIOLoop) - , mConnector(aConnector) - , mPeerAddressLength(0) -{ - MOZ_ASSERT(mConnector); - - MOZ_COUNT_CTOR_INHERITED(ConnectionOrientedSocketIO, DataSocketIO); -} - -ConnectionOrientedSocketIO::~ConnectionOrientedSocketIO() -{ - MOZ_COUNT_DTOR_INHERITED(ConnectionOrientedSocketIO, DataSocketIO); -} - -nsresult -ConnectionOrientedSocketIO::Accept(int aFd, - const struct sockaddr* aPeerAddress, - socklen_t aPeerAddressLength) -{ - MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); - MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_CONNECTING); - - SetSocket(aFd, SOCKET_IS_CONNECTED); - - // Address setup - mPeerAddressLength = aPeerAddressLength; - memcpy(&mPeerAddress, aPeerAddress, mPeerAddressLength); - - // Signal success and start data transfer - OnConnected(); - - return NS_OK; -} - -nsresult -ConnectionOrientedSocketIO::Connect() -{ - MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); - MOZ_ASSERT(!IsOpen()); - - struct sockaddr* peerAddress = - reinterpret_cast<struct sockaddr*>(&mPeerAddress); - mPeerAddressLength = sizeof(mPeerAddress); - - int fd; - nsresult rv = mConnector->CreateStreamSocket(peerAddress, - &mPeerAddressLength, - fd); - if (NS_FAILED(rv)) { - // Tell the consumer thread we've errored - GetConsumerThread()->PostTask( - MakeAndAddRef<SocketEventTask>(this, SocketEventTask::CONNECT_ERROR)); - return NS_ERROR_FAILURE; - } - - SetFd(fd); - - // calls OnConnected() on success, or OnError() otherwise - rv = UnixSocketWatcher::Connect(peerAddress, mPeerAddressLength); - - if (NS_FAILED(rv)) { - return rv; - } - - return NS_OK; -} - -void -ConnectionOrientedSocketIO::Send(UnixSocketIOBuffer* aBuffer) -{ - MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); - - EnqueueData(aBuffer); - AddWatchers(WRITE_WATCHER, false); -} - -// |UnixSocketWatcher| - -void -ConnectionOrientedSocketIO::OnSocketCanReceiveWithoutBlocking() -{ - MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); - MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_CONNECTED); // see bug 990984 - - ssize_t res = ReceiveData(GetFd()); - if (res < 0) { - /* I/O error */ - RemoveWatchers(READ_WATCHER|WRITE_WATCHER); - } else if (!res) { - /* EOF or peer shutdown */ - RemoveWatchers(READ_WATCHER); - } -} - -void -ConnectionOrientedSocketIO::OnSocketCanSendWithoutBlocking() -{ - MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); - MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_CONNECTED); // see bug 990984 - MOZ_ASSERT(!IsShutdownOnIOThread()); - - nsresult rv = SendPendingData(GetFd()); - if (NS_FAILED(rv)) { - return; - } - - if (HasPendingData()) { - AddWatchers(WRITE_WATCHER, false); - } -} - -void -ConnectionOrientedSocketIO::OnConnected() -{ - MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); - MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_CONNECTED); - - GetConsumerThread()->PostTask( - MakeAndAddRef<SocketEventTask>(this, SocketEventTask::CONNECT_SUCCESS)); - - AddWatchers(READ_WATCHER, true); - if (HasPendingData()) { - AddWatchers(WRITE_WATCHER, false); - } -} - -void -ConnectionOrientedSocketIO::OnListening() -{ - MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); - - NS_NOTREACHED("Invalid call to |ConnectionOrientedSocketIO::OnListening|"); -} - -void -ConnectionOrientedSocketIO::OnError(const char* aFunction, int aErrno) -{ - MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); - - UnixFdWatcher::OnError(aFunction, aErrno); - - // Clean up watchers, status, fd - Close(); - - // Tell the consumer thread we've errored - GetConsumerThread()->PostTask( - MakeAndAddRef<SocketEventTask>(this, SocketEventTask::CONNECT_ERROR)); -} - -// -// ConnectionOrientedSocket -// - -ConnectionOrientedSocket::ConnectionOrientedSocket() -{ - MOZ_COUNT_CTOR_INHERITED(ConnectionOrientedSocket, DataSocket); -} - -ConnectionOrientedSocket::~ConnectionOrientedSocket() -{ - MOZ_COUNT_DTOR_INHERITED(ConnectionOrientedSocket, DataSocket); -} - -} -} diff --git a/ipc/unixsocket/ConnectionOrientedSocket.h b/ipc/unixsocket/ConnectionOrientedSocket.h deleted file mode 100644 index a1236ec4a..000000000 --- a/ipc/unixsocket/ConnectionOrientedSocket.h +++ /dev/null @@ -1,122 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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/. */ - -#ifndef mozilla_ipc_ConnectionOrientedSocket_h -#define mozilla_ipc_ConnectionOrientedSocket_h - -#include <sys/socket.h> -#include "DataSocket.h" -#include "mozilla/ipc/UnixSocketWatcher.h" - -class MessageLoop; - -namespace mozilla { -namespace ipc { - -class UnixSocketConnector; - -/* - * |ConnectionOrientedSocketIO| and |ConnectionOrientedSocket| define - * interfaces for implementing stream sockets on I/O and consumer thread. - * |ListenSocket| uses these classes to handle accepted sockets. - */ - -class ConnectionOrientedSocketIO - : public DataSocketIO - , public UnixSocketWatcher -{ -public: - virtual ~ConnectionOrientedSocketIO(); - - nsresult Accept(int aFd, - const struct sockaddr* aAddress, - socklen_t aAddressLength); - - nsresult Connect(); - - void Send(UnixSocketIOBuffer* aBuffer); - - // Methods for |UnixSocketWatcher| - // - - void OnSocketCanReceiveWithoutBlocking() final; - void OnSocketCanSendWithoutBlocking() final; - - void OnListening() final; - void OnConnected() final; - void OnError(const char* aFunction, int aErrno) final; - -protected: - /** - * Constructs an instance of |ConnectionOrientedSocketIO| - * - * @param aConsumerLoop The socket's consumer thread. - * @param aIOLoop The socket's I/O loop. - * @param aFd The socket file descriptor. - * @param aConnectionStatus The connection status for |aFd|. - * @param aConnector Connector object for socket-type-specific methods. - */ - ConnectionOrientedSocketIO(MessageLoop* aConsumerLoop, - MessageLoop* aIOLoop, - int aFd, ConnectionStatus aConnectionStatus, - UnixSocketConnector* aConnector); - - /** - * Constructs an instance of |ConnectionOrientedSocketIO| - * - * @param aConsumerLoop The socket's consumer thread. - * @param aIOLoop The socket's I/O loop. - * @param aConnector Connector object for socket-type-specific methods. - */ - ConnectionOrientedSocketIO(MessageLoop* aConsumerLoop, - MessageLoop* aIOLoop, - UnixSocketConnector* aConnector); - -private: - /** - * Connector object used to create the connection we are currently using. - */ - UniquePtr<UnixSocketConnector> mConnector; - - /** - * Number of valid bytes in |mPeerAddress|. - */ - socklen_t mPeerAddressLength; - - /** - * Address of the socket's current peer. - */ - struct sockaddr_storage mPeerAddress; -}; - -class ConnectionOrientedSocket : public DataSocket -{ -public: - /** - * Prepares an instance of |ConnectionOrientedSocket| in DISCONNECTED - * state for accepting a connection. Consumer-thread only. - * - * @param aConnector The new connector object, owned by the - * connection-oriented socket. - * @param aConsumerLoop The socket's consumer thread. - * @param aIOLoop The socket's I/O thread. - * @param[out] aIO, Returns an instance of |ConnectionOrientedSocketIO|. - * @return NS_OK on success, or an XPCOM error code otherwise. - */ - virtual nsresult PrepareAccept(UnixSocketConnector* aConnector, - MessageLoop* aConsumerLoop, - MessageLoop* aIOLoop, - ConnectionOrientedSocketIO*& aIO) = 0; - -protected: - ConnectionOrientedSocket(); - virtual ~ConnectionOrientedSocket(); -}; - -} -} - -#endif // mozilla_ipc_ConnectionOrientedSocket diff --git a/ipc/unixsocket/DataSocket.cpp b/ipc/unixsocket/DataSocket.cpp deleted file mode 100644 index 057c59203..000000000 --- a/ipc/unixsocket/DataSocket.cpp +++ /dev/null @@ -1,136 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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 "DataSocket.h" -#ifdef MOZ_TASK_TRACER -#include "GeckoTaskTracer.h" -#endif -#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, MOZ_COUNT_DTOR - -#ifdef MOZ_TASK_TRACER -using namespace mozilla::tasktracer; -#endif - -namespace mozilla { -namespace ipc { - -// -// DataSocketIO -// - -DataSocketIO::~DataSocketIO() -{ - MOZ_COUNT_DTOR_INHERITED(DataSocketIO, SocketIOBase); -} - -void -DataSocketIO::EnqueueData(UnixSocketIOBuffer* aBuffer) -{ - if (!aBuffer->GetSize()) { - delete aBuffer; // delete empty data immediately - return; - } - mOutgoingQ.AppendElement(aBuffer); -} - -bool -DataSocketIO::HasPendingData() const -{ - return !mOutgoingQ.IsEmpty(); -} - -ssize_t -DataSocketIO::ReceiveData(int aFd) -{ - MOZ_ASSERT(aFd >= 0); - - UnixSocketIOBuffer* incoming; - nsresult rv = QueryReceiveBuffer(&incoming); - if (NS_FAILED(rv)) { - /* an error occured */ - GetConsumerThread()->PostTask( - MakeAndAddRef<SocketRequestClosingTask>(this)); - return -1; - } - - ssize_t res = incoming->Receive(aFd); - if (res < 0) { - /* an I/O error occured */ - DiscardBuffer(); - GetConsumerThread()->PostTask( - MakeAndAddRef<SocketRequestClosingTask>(this)); - return -1; - } else if (!res) { - /* EOF or peer shut down sending */ - DiscardBuffer(); - GetConsumerThread()->PostTask( - MakeAndAddRef<SocketRequestClosingTask>(this)); - return 0; - } - -#ifdef MOZ_TASK_TRACER - /* Make unix socket creation events to be the source events of TaskTracer, - * and originate the rest correlation tasks from here. - */ - AutoSourceEvent taskTracerEvent(SourceEventType::Unixsocket); -#endif - - ConsumeBuffer(); - - return res; -} - -nsresult -DataSocketIO::SendPendingData(int aFd) -{ - MOZ_ASSERT(aFd >= 0); - - while (HasPendingData()) { - UnixSocketIOBuffer* outgoing = mOutgoingQ.ElementAt(0); - - ssize_t res = outgoing->Send(aFd); - if (res < 0) { - /* an I/O error occured */ - GetConsumerThread()->PostTask( - MakeAndAddRef<SocketRequestClosingTask>(this)); - return NS_ERROR_FAILURE; - } else if (!res && outgoing->GetSize()) { - /* I/O is currently blocked; try again later */ - return NS_OK; - } - if (!outgoing->GetSize()) { - mOutgoingQ.RemoveElementAt(0); - delete outgoing; - } - } - - return NS_OK; -} - -DataSocketIO::DataSocketIO(MessageLoop* aConsumerLoop) - : SocketIOBase(aConsumerLoop) -{ - MOZ_COUNT_CTOR_INHERITED(DataSocketIO, SocketIOBase); -} - -// -// DataSocket -// - -DataSocket::DataSocket() -{ - MOZ_COUNT_CTOR_INHERITED(DataSocket, SocketBase); -} - -DataSocket::~DataSocket() -{ - MOZ_COUNT_DTOR_INHERITED(DataSocket, SocketBase); -} - -} -} diff --git a/ipc/unixsocket/DataSocket.h b/ipc/unixsocket/DataSocket.h deleted file mode 100644 index 454333461..000000000 --- a/ipc/unixsocket/DataSocket.h +++ /dev/null @@ -1,145 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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/. - */ - -#ifndef mozilla_ipc_datasocket_h -#define mozilla_ipc_datasocket_h - -#include "mozilla/ipc/SocketBase.h" -#include "nsTArray.h" - -namespace mozilla { -namespace ipc { - -// -// DataSocket -// - -/** - * |DataSocket| represents a socket that can send or receive data. This - * can be a stream-based socket, a datagram-based socket, or any other - * socket that transfers data. - */ -class DataSocket : public SocketBase -{ -public: - virtual ~DataSocket(); - - /** - * Queue data to be sent to the socket on the IO thread. Can only be called on - * originating thread. - * - * @param aBuffer Data to be sent to socket - */ - virtual void SendSocketData(UnixSocketIOBuffer* aBuffer) = 0; - -protected: - DataSocket(); -}; - -// -// DataSocketIO -// - -/** - * |DataSocketIO| is a base class for Socket I/O classes that - * transfer data on the I/O thread. It provides methods for the - * most common read and write scenarios. - */ -class DataSocketIO : public SocketIOBase -{ -public: - virtual ~DataSocketIO(); - - /** - * Allocates a buffer for receiving data from the socket. The method - * shall return the buffer in the arguments. The buffer is owned by the - * I/O class. |DataSocketIO| will never ask for more than one buffer - * at a time, so I/O classes can handout the same buffer on each invokation - * of this method. I/O-thread only. - * - * @param[out] aBuffer returns a pointer to the I/O buffer - * @return NS_OK on success, or an error code otherwise - */ - virtual nsresult QueryReceiveBuffer(UnixSocketIOBuffer** aBuffer) = 0; - - /** - * Marks the current socket buffer to by consumed by the I/O class. The - * class is resonsible for releasing the buffer afterwards. I/O-thread - * only. - * - * @param aIndex the socket's index - * @param[out] aBuffer the receive buffer - * @param[out] aSize the receive buffer's size - */ - virtual void ConsumeBuffer() = 0; - - /** - * Marks the current socket buffer to be discarded. The I/O class is - * resonsible for releasing the buffer's memory. I/O-thread only. - * - * @param aIndex the socket's index - */ - virtual void DiscardBuffer() = 0; - - void EnqueueData(UnixSocketIOBuffer* aBuffer); - bool HasPendingData() const; - - ssize_t ReceiveData(int aFd); - - nsresult SendPendingData(int aFd); - -protected: - DataSocketIO(MessageLoop* aConsumerLoop); - -private: - /** - * Raw data queue. Must be pushed/popped from I/O thread only. - */ - nsTArray<UnixSocketIOBuffer*> mOutgoingQ; -}; - -// -// Tasks -// - -/* |SocketIOSendTask| transfers an instance of |Tdata|, such as - * |UnixSocketRawData|, to the I/O thread and queues it up for - * sending the contained data. - */ -template<typename Tio, typename Tdata> -class SocketIOSendTask final : public SocketIOTask<Tio> -{ -public: - SocketIOSendTask(Tio* aIO, Tdata* aData) - : SocketIOTask<Tio>(aIO) - , mData(aData) - { - MOZ_ASSERT(aData); - } - - NS_IMETHOD Run() override - { - MOZ_ASSERT(!SocketIOTask<Tio>::IsCanceled()); - - Tio* io = SocketIOTask<Tio>::GetIO(); - MOZ_ASSERT(!io->IsConsumerThread()); - MOZ_ASSERT(!io->IsShutdownOnIOThread()); - - io->Send(mData); - - return NS_OK; - } - -private: - Tdata* mData; -}; - -} -} - -#endif diff --git a/ipc/unixsocket/ListenSocket.cpp b/ipc/unixsocket/ListenSocket.cpp deleted file mode 100644 index c05a4d701..000000000 --- a/ipc/unixsocket/ListenSocket.cpp +++ /dev/null @@ -1,432 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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 "ListenSocket.h" -#include <fcntl.h> -#include "ConnectionOrientedSocket.h" -#include "DataSocket.h" -#include "ListenSocketConsumer.h" -#include "mozilla/DebugOnly.h" -#include "mozilla/RefPtr.h" -#include "mozilla/Unused.h" -#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, MOZ_COUNT_DTOR -#include "nsXULAppAPI.h" -#include "UnixSocketConnector.h" - -namespace mozilla { -namespace ipc { - -// -// ListenSocketIO -// - -class ListenSocketIO final - : public UnixSocketWatcher - , public SocketIOBase -{ -public: - class ListenTask; - - ListenSocketIO(MessageLoop* aConsumerLoop, - MessageLoop* aIOLoop, - ListenSocket* aListenSocket, - UnixSocketConnector* aConnector); - ~ListenSocketIO(); - - UnixSocketConnector* GetConnector() const; - - // Task callback methods - // - - /** - * Run bind/listen to prepare for further runs of accept() - */ - void Listen(ConnectionOrientedSocketIO* aCOSocketIO); - - // I/O callback methods - // - - void OnConnected() override; - void OnError(const char* aFunction, int aErrno) override; - void OnListening() override; - void OnSocketCanAcceptWithoutBlocking() override; - - // Methods for |SocketIOBase| - // - - SocketBase* GetSocketBase() override; - - bool IsShutdownOnConsumerThread() const override; - bool IsShutdownOnIOThread() const override; - - void ShutdownOnConsumerThread() override; - void ShutdownOnIOThread() override; - -private: - void FireSocketError(); - - /** - * Consumer pointer. Non-thread-safe pointer, so should only be manipulated - * directly from consumer thread. All non-consumer-thread accesses should - * happen with mIO as container. - */ - ListenSocket* mListenSocket; - - /** - * Connector object used to create the connection we are currently using. - */ - UniquePtr<UnixSocketConnector> mConnector; - - /** - * If true, do not requeue whatever task we're running - */ - bool mShuttingDownOnIOThread; - - /** - * Number of valid bytes in |mAddress| - */ - socklen_t mAddressLength; - - /** - * Address structure of the socket currently in use - */ - struct sockaddr_storage mAddress; - - ConnectionOrientedSocketIO* mCOSocketIO; -}; - -ListenSocketIO::ListenSocketIO(MessageLoop* aConsumerLoop, - MessageLoop* aIOLoop, - ListenSocket* aListenSocket, - UnixSocketConnector* aConnector) - : UnixSocketWatcher(aIOLoop) - , SocketIOBase(aConsumerLoop) - , mListenSocket(aListenSocket) - , mConnector(aConnector) - , mShuttingDownOnIOThread(false) - , mAddressLength(0) - , mCOSocketIO(nullptr) -{ - MOZ_ASSERT(mListenSocket); - MOZ_ASSERT(mConnector); - - MOZ_COUNT_CTOR_INHERITED(ListenSocketIO, SocketIOBase); -} - -ListenSocketIO::~ListenSocketIO() -{ - MOZ_ASSERT(IsConsumerThread()); - MOZ_ASSERT(IsShutdownOnConsumerThread()); - - MOZ_COUNT_DTOR_INHERITED(ListenSocketIO, SocketIOBase); -} - -UnixSocketConnector* -ListenSocketIO::GetConnector() const -{ - return mConnector.get(); -} - -void -ListenSocketIO::Listen(ConnectionOrientedSocketIO* aCOSocketIO) -{ - MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); - MOZ_ASSERT(mConnector); - MOZ_ASSERT(aCOSocketIO); - - struct sockaddr* address = reinterpret_cast<struct sockaddr*>(&mAddress); - mAddressLength = sizeof(mAddress); - - if (!IsOpen()) { - int fd; - nsresult rv = mConnector->CreateListenSocket(address, &mAddressLength, - fd); - if (NS_FAILED(rv)) { - FireSocketError(); - return; - } - SetFd(fd); - } - - mCOSocketIO = aCOSocketIO; - - // calls OnListening on success, or OnError otherwise - DebugOnly<nsresult> rv = UnixSocketWatcher::Listen(address, mAddressLength); - NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Listen failed"); -} - -void -ListenSocketIO::OnConnected() -{ - MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); - - NS_NOTREACHED("Invalid call to |ListenSocketIO::OnConnected|"); -} - -void -ListenSocketIO::OnListening() -{ - MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); - MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_LISTENING); - - AddWatchers(READ_WATCHER, true); - - /* We signal a successful 'connection' to a local address for listening. */ - GetConsumerThread()->PostTask( - MakeAndAddRef<SocketEventTask>(this, SocketEventTask::CONNECT_SUCCESS)); -} - -void -ListenSocketIO::OnError(const char* aFunction, int aErrno) -{ - MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); - - UnixFdWatcher::OnError(aFunction, aErrno); - FireSocketError(); -} - -void -ListenSocketIO::FireSocketError() -{ - MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); - - // Clean up watchers, statuses, fds - Close(); - - // Tell the consumer thread we've errored - GetConsumerThread()->PostTask( - MakeAndAddRef<SocketEventTask>(this, SocketEventTask::CONNECT_ERROR)); -} - -void -ListenSocketIO::OnSocketCanAcceptWithoutBlocking() -{ - MOZ_ASSERT(MessageLoopForIO::current() == GetIOLoop()); - MOZ_ASSERT(GetConnectionStatus() == SOCKET_IS_LISTENING); - MOZ_ASSERT(mCOSocketIO); - - RemoveWatchers(READ_WATCHER|WRITE_WATCHER); - - struct sockaddr_storage storage; - socklen_t addressLength = sizeof(storage); - - int fd; - nsresult rv = mConnector->AcceptStreamSocket( - GetFd(), - reinterpret_cast<struct sockaddr*>(&storage), &addressLength, - fd); - if (NS_FAILED(rv)) { - FireSocketError(); - return; - } - - mCOSocketIO->Accept(fd, - reinterpret_cast<struct sockaddr*>(&storage), - addressLength); -} - -// |SocketIOBase| - -SocketBase* -ListenSocketIO::GetSocketBase() -{ - return mListenSocket; -} - -bool -ListenSocketIO::IsShutdownOnConsumerThread() const -{ - MOZ_ASSERT(IsConsumerThread()); - - return mListenSocket == nullptr; -} - -bool -ListenSocketIO::IsShutdownOnIOThread() const -{ - return mShuttingDownOnIOThread; -} - -void -ListenSocketIO::ShutdownOnConsumerThread() -{ - MOZ_ASSERT(IsConsumerThread()); - MOZ_ASSERT(!IsShutdownOnConsumerThread()); - - mListenSocket = nullptr; -} - -void -ListenSocketIO::ShutdownOnIOThread() -{ - MOZ_ASSERT(!IsConsumerThread()); - MOZ_ASSERT(!mShuttingDownOnIOThread); - - Close(); // will also remove fd from I/O loop - mShuttingDownOnIOThread = true; -} - -// -// Socket tasks -// - -class ListenSocketIO::ListenTask final : public SocketIOTask<ListenSocketIO> -{ -public: - ListenTask(ListenSocketIO* aIO, ConnectionOrientedSocketIO* aCOSocketIO) - : SocketIOTask<ListenSocketIO>(aIO) - , mCOSocketIO(aCOSocketIO) - { - MOZ_ASSERT(mCOSocketIO); - - MOZ_COUNT_CTOR(ListenTask); - } - - ~ListenTask() - { - MOZ_COUNT_DTOR(ListenTask); - } - - NS_IMETHOD Run() override - { - MOZ_ASSERT(!GetIO()->IsConsumerThread()); - - if (!IsCanceled()) { - GetIO()->Listen(mCOSocketIO); - } - return NS_OK; - } - -private: - ConnectionOrientedSocketIO* mCOSocketIO; -}; - -// -// ListenSocket -// - -ListenSocket::ListenSocket(ListenSocketConsumer* aConsumer, int aIndex) - : mIO(nullptr) - , mConsumer(aConsumer) - , mIndex(aIndex) -{ - MOZ_ASSERT(mConsumer); - - MOZ_COUNT_CTOR_INHERITED(ListenSocket, SocketBase); -} - -ListenSocket::~ListenSocket() -{ - MOZ_ASSERT(!mIO); - - MOZ_COUNT_DTOR_INHERITED(ListenSocket, SocketBase); -} - -nsresult -ListenSocket::Listen(UnixSocketConnector* aConnector, - MessageLoop* aConsumerLoop, - MessageLoop* aIOLoop, - ConnectionOrientedSocket* aCOSocket) -{ - MOZ_ASSERT(!mIO); - - mIO = new ListenSocketIO(aConsumerLoop, aIOLoop, this, aConnector); - - // Prepared I/O object, now start listening. - nsresult rv = Listen(aCOSocket); - if (NS_FAILED(rv)) { - delete mIO; - mIO = nullptr; - return rv; - } - - return NS_OK; -} - -nsresult -ListenSocket::Listen(UnixSocketConnector* aConnector, - ConnectionOrientedSocket* aCOSocket) -{ - return Listen(aConnector, MessageLoop::current(), XRE_GetIOMessageLoop(), - aCOSocket); -} - -nsresult -ListenSocket::Listen(ConnectionOrientedSocket* aCOSocket) -{ - MOZ_ASSERT(aCOSocket); - MOZ_ASSERT(mIO); - - // We first prepare the connection-oriented socket with a - // socket connector and a socket I/O class. - - UniquePtr<UnixSocketConnector> connector; - nsresult rv = mIO->GetConnector()->Duplicate(connector); - if (NS_FAILED(rv)) { - return rv; - } - - ConnectionOrientedSocketIO* io; - rv = aCOSocket->PrepareAccept(connector.get(), - mIO->GetConsumerThread(), mIO->GetIOLoop(), - io); - if (NS_FAILED(rv)) { - return rv; - } - - Unused << connector.release(); // now owned by |io| - - // Then we start listening for connection requests. - - SetConnectionStatus(SOCKET_LISTENING); - - mIO->GetIOLoop()->PostTask( - MakeAndAddRef<ListenSocketIO::ListenTask>(mIO, io)); - - return NS_OK; -} - -// |SocketBase| - -void -ListenSocket::Close() -{ - if (!mIO) { - return; - } - - MOZ_ASSERT(mIO->IsConsumerThread()); - - // From this point on, we consider mIO as being deleted. We sever - // the relationship here so any future calls to listen or connect - // will create a new implementation. - mIO->ShutdownOnConsumerThread(); - mIO->GetIOLoop()->PostTask(MakeAndAddRef<SocketIOShutdownTask>(mIO)); - mIO = nullptr; - - NotifyDisconnect(); -} - -void -ListenSocket::OnConnectSuccess() -{ - mConsumer->OnConnectSuccess(mIndex); -} - -void -ListenSocket::OnConnectError() -{ - mConsumer->OnConnectError(mIndex); -} - -void -ListenSocket::OnDisconnect() -{ - mConsumer->OnDisconnect(mIndex); -} - -} // namespace ipc -} // namespace mozilla diff --git a/ipc/unixsocket/ListenSocket.h b/ipc/unixsocket/ListenSocket.h deleted file mode 100644 index 9bde4602d..000000000 --- a/ipc/unixsocket/ListenSocket.h +++ /dev/null @@ -1,93 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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/. */ - -#ifndef mozilla_ipc_ListenSocket_h -#define mozilla_ipc_ListenSocket_h - -#include "mozilla/ipc/SocketBase.h" -#include "nsString.h" - -class MessageLoop; - -namespace mozilla { -namespace ipc { - -class ConnectionOrientedSocket; -class ListenSocketConsumer; -class ListenSocketIO; -class UnixSocketConnector; - -class ListenSocket final : public SocketBase -{ -public: - /** - * Constructs an instance of |ListenSocket|. - * - * @param aConsumer The consumer for the socket. - * @param aIndex An arbitrary index. - */ - ListenSocket(ListenSocketConsumer* aConsumer, int aIndex); - - /** - * Starts a task on the socket that will try to accept a new connection - * in a non-blocking manner. - * - * @param aConnector Connector object for socket-type-specific functions - * @param aConsumerLoop The socket's consumer thread. - * @param aIOLoop The socket's I/O thread. - * @param aCOSocket The connection-oriented socket for handling the - * accepted connection. - * @return NS_OK on success, or an XPCOM error code otherwise. - */ - nsresult Listen(UnixSocketConnector* aConnector, - MessageLoop* aConsumerLoop, - MessageLoop* aIOLoop, - ConnectionOrientedSocket* aCOSocket); - - /** - * Starts a task on the socket that will try to accept a new connection - * in a non-blocking manner. - * - * @param aConnector Connector object for socket-type-specific functions - * @param aCOSocket The connection-oriented socket for handling the - * accepted connection. - * @return NS_OK on success, or an XPCOM error code otherwise. - */ - nsresult Listen(UnixSocketConnector* aConnector, - ConnectionOrientedSocket* aCOSocket); - - /** - * Starts a task on the socket that will try to accept a new connection - * in a non-blocking manner. This method re-uses a previously created - * listen socket. - * - * @param aCOSocket The connection-oriented socket for handling the - * accepted connection. - * @return NS_OK on success, or an XPCOM error code otherwise. - */ - nsresult Listen(ConnectionOrientedSocket* aCOSocket); - - // Methods for |SocketBase| - // - - void Close() override; - void OnConnectSuccess() override; - void OnConnectError() override; - void OnDisconnect() override; - -protected: - virtual ~ListenSocket(); - -private: - ListenSocketIO* mIO; - ListenSocketConsumer* mConsumer; - int mIndex; -}; - -} // namespace ipc -} // namepsace mozilla - -#endif // mozilla_ipc_ListenSocket_h diff --git a/ipc/unixsocket/ListenSocketConsumer.cpp b/ipc/unixsocket/ListenSocketConsumer.cpp deleted file mode 100644 index f4de0c42e..000000000 --- a/ipc/unixsocket/ListenSocketConsumer.cpp +++ /dev/null @@ -1,20 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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 "ListenSocketConsumer.h" - -namespace mozilla { -namespace ipc { - -// -// ListenSocketConsumer -// - -ListenSocketConsumer::~ListenSocketConsumer() -{ } - -} -} diff --git a/ipc/unixsocket/ListenSocketConsumer.h b/ipc/unixsocket/ListenSocketConsumer.h deleted file mode 100644 index 8c9af3019..000000000 --- a/ipc/unixsocket/ListenSocketConsumer.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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/. */ - -#ifndef mozilla_ipc_listensocketconsumer_h -#define mozilla_ipc_listensocketconsumer_h - -namespace mozilla { -namespace ipc { - -/** - * |ListenSocketConsumer| handles socket events. - */ -class ListenSocketConsumer -{ -public: - virtual ~ListenSocketConsumer(); - - /** - * Callback for socket success. Consumer-thread only. - * - * @param aIndex The index that has been given to the listening socket. - */ - virtual void OnConnectSuccess(int aIndex) = 0; - - /** - * Callback for socket errors. Consumer-thread only. - * - * @param aIndex The index that has been given to the listening socket. - */ - virtual void OnConnectError(int aIndex) = 0; - - /** - * Callback for socket disconnect. Consumer-thread only. - * - * @param aIndex The index that has been given to the listeing socket. - */ - virtual void OnDisconnect(int aIndex) = 0; -}; - -} -} - -#endif diff --git a/ipc/unixsocket/SocketBase.cpp b/ipc/unixsocket/SocketBase.cpp deleted file mode 100644 index b11729652..000000000 --- a/ipc/unixsocket/SocketBase.cpp +++ /dev/null @@ -1,449 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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 "SocketBase.h" -#include <errno.h> -#include <string.h> -#include <unistd.h> -#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, MOZ_COUNT_DTOR - -namespace mozilla { -namespace ipc { - -// -// UnixSocketIOBuffer -// - -UnixSocketBuffer::UnixSocketBuffer() - : mSize(0) - , mOffset(0) - , mAvailableSpace(0) - , mData(nullptr) -{ - MOZ_COUNT_CTOR(UnixSocketBuffer); -} - -UnixSocketBuffer::~UnixSocketBuffer() -{ - MOZ_COUNT_DTOR(UnixSocketBuffer); - - // Make sure that the caller released the buffer's memory. - MOZ_ASSERT(!GetBuffer()); -} - -const uint8_t* -UnixSocketBuffer::Consume(size_t aLen) -{ - if (NS_WARN_IF(GetSize() < aLen)) { - return nullptr; - } - uint8_t* data = mData + mOffset; - mOffset += aLen; - return data; -} - -nsresult -UnixSocketBuffer::Read(void* aValue, size_t aLen) -{ - const uint8_t* data = Consume(aLen); - if (!data) { - return NS_ERROR_OUT_OF_MEMORY; - } - memcpy(aValue, data, aLen); - return NS_OK; -} - -uint8_t* -UnixSocketBuffer::Append(size_t aLen) -{ - if (((mAvailableSpace - mSize) < aLen)) { - size_t availableSpace = mAvailableSpace + std::max(mAvailableSpace, aLen); - uint8_t* data = new uint8_t[availableSpace]; - memcpy(data, mData, mSize); - mData = data; - mAvailableSpace = availableSpace; - } - uint8_t* data = mData + mSize; - mSize += aLen; - return data; -} - -nsresult -UnixSocketBuffer::Write(const void* aValue, size_t aLen) -{ - uint8_t* data = Append(aLen); - if (!data) { - return NS_ERROR_OUT_OF_MEMORY; - } - memcpy(data, aValue, aLen); - return NS_OK; -} - -void -UnixSocketBuffer::CleanupLeadingSpace() -{ - if (GetLeadingSpace()) { - if (GetSize() <= GetLeadingSpace()) { - memcpy(mData, GetData(), GetSize()); - } else { - memmove(mData, GetData(), GetSize()); - } - mOffset = 0; - } -} - -// -// UnixSocketIOBuffer -// - -UnixSocketIOBuffer::UnixSocketIOBuffer() -{ - MOZ_COUNT_CTOR_INHERITED(UnixSocketIOBuffer, UnixSocketBuffer); -} - -UnixSocketIOBuffer::~UnixSocketIOBuffer() -{ - MOZ_COUNT_DTOR_INHERITED(UnixSocketIOBuffer, UnixSocketBuffer); -} - -// -// UnixSocketRawData -// - -UnixSocketRawData::UnixSocketRawData(const void* aData, size_t aSize) -{ - MOZ_ASSERT(aData || !aSize); - - MOZ_COUNT_CTOR_INHERITED(UnixSocketRawData, UnixSocketIOBuffer); - - ResetBuffer(static_cast<uint8_t*>(memcpy(new uint8_t[aSize], aData, aSize)), - 0, aSize, aSize); -} - -UnixSocketRawData::UnixSocketRawData(UniquePtr<uint8_t[]> aData, size_t aSize) -{ - MOZ_ASSERT(aData || !aSize); - - MOZ_COUNT_CTOR_INHERITED(UnixSocketRawData, UnixSocketIOBuffer); - - ResetBuffer(aData.release(), 0, aSize, aSize); -} - -UnixSocketRawData::UnixSocketRawData(size_t aSize) -{ - MOZ_COUNT_CTOR_INHERITED(UnixSocketRawData, UnixSocketIOBuffer); - - ResetBuffer(new uint8_t[aSize], 0, 0, aSize); -} - -UnixSocketRawData::~UnixSocketRawData() -{ - MOZ_COUNT_DTOR_INHERITED(UnixSocketRawData, UnixSocketIOBuffer); - - UniquePtr<uint8_t[]> data(GetBuffer()); - ResetBuffer(nullptr, 0, 0, 0); -} - -ssize_t -UnixSocketRawData::Receive(int aFd) -{ - if (!GetTrailingSpace()) { - if (!GetLeadingSpace()) { - return -1; /* buffer is full */ - } - /* free up space at the end of data buffer */ - CleanupLeadingSpace(); - } - - ssize_t res = - TEMP_FAILURE_RETRY(read(aFd, GetTrailingBytes(), GetTrailingSpace())); - - if (res < 0) { - /* I/O error */ - return -1; - } else if (!res) { - /* EOF or peer shutdown sending */ - return 0; - } - - Append(res); /* mark read data as 'valid' */ - - return res; -} - -ssize_t -UnixSocketRawData::Send(int aFd) -{ - if (!GetSize()) { - return 0; - } - - ssize_t res = TEMP_FAILURE_RETRY(write(aFd, GetData(), GetSize())); - - if (res < 0) { - if (errno == EAGAIN || errno == EWOULDBLOCK) { - return 0; /* socket is blocked; try again later */ - } - return -1; - } else if (!res) { - /* nothing written */ - return 0; - } - - Consume(res); - - return res; -} - -// -// SocketBase -// - -SocketConnectionStatus -SocketBase::GetConnectionStatus() const -{ - return mConnectionStatus; -} - -int -SocketBase::GetSuggestedConnectDelayMs() const -{ - return mConnectDelayMs; -} - -void -SocketBase::NotifySuccess() -{ - mConnectionStatus = SOCKET_CONNECTED; - mConnectTimestamp = PR_IntervalNow(); - OnConnectSuccess(); -} - -void -SocketBase::NotifyError() -{ - mConnectionStatus = SOCKET_DISCONNECTED; - mConnectDelayMs = CalculateConnectDelayMs(); - mConnectTimestamp = 0; - OnConnectError(); -} - -void -SocketBase::NotifyDisconnect() -{ - mConnectionStatus = SOCKET_DISCONNECTED; - mConnectDelayMs = CalculateConnectDelayMs(); - mConnectTimestamp = 0; - OnDisconnect(); -} - -uint32_t -SocketBase::CalculateConnectDelayMs() const -{ - uint32_t connectDelayMs = mConnectDelayMs; - - if (mConnectTimestamp && (PR_IntervalNow()-mConnectTimestamp) > connectDelayMs) { - // reset delay if connection has been opened for a while, or... - connectDelayMs = 0; - } else if (!connectDelayMs) { - // ...start with a delay of ~1 sec, or... - connectDelayMs = 1<<10; - } else if (connectDelayMs < (1<<16)) { - // ...otherwise increase delay by a factor of 2 - connectDelayMs <<= 1; - } - return connectDelayMs; -} - -SocketBase::SocketBase() -: mConnectionStatus(SOCKET_DISCONNECTED) -, mConnectTimestamp(0) -, mConnectDelayMs(0) -{ - MOZ_COUNT_CTOR(SocketBase); -} - -SocketBase::~SocketBase() -{ - MOZ_ASSERT(mConnectionStatus == SOCKET_DISCONNECTED); - - MOZ_COUNT_DTOR(SocketBase); -} - -void -SocketBase::SetConnectionStatus(SocketConnectionStatus aConnectionStatus) -{ - mConnectionStatus = aConnectionStatus; -} - -// -// SocketIOBase -// - -SocketIOBase::SocketIOBase(MessageLoop* aConsumerLoop) - : mConsumerLoop(aConsumerLoop) -{ - MOZ_ASSERT(mConsumerLoop); - - MOZ_COUNT_CTOR(SocketIOBase); -} - -SocketIOBase::~SocketIOBase() -{ - MOZ_COUNT_DTOR(SocketIOBase); -} - -MessageLoop* -SocketIOBase::GetConsumerThread() const -{ - return mConsumerLoop; -} - -bool -SocketIOBase::IsConsumerThread() const -{ - return GetConsumerThread() == MessageLoop::current(); -} - -// -// SocketEventTask -// - -SocketEventTask::SocketEventTask(SocketIOBase* aIO, SocketEvent aEvent) - : SocketTask<SocketIOBase>(aIO) - , mEvent(aEvent) -{ - MOZ_COUNT_CTOR(SocketEventTask); -} - -SocketEventTask::~SocketEventTask() -{ - MOZ_COUNT_DTOR(SocketEventTask); -} - -NS_IMETHODIMP -SocketEventTask::Run() -{ - SocketIOBase* io = SocketTask<SocketIOBase>::GetIO(); - - MOZ_ASSERT(io->IsConsumerThread()); - - if (NS_WARN_IF(io->IsShutdownOnConsumerThread())) { - // Since we've already explicitly closed and the close - // happened before this, this isn't really an error. - return NS_OK; - } - - SocketBase* socketBase = io->GetSocketBase(); - MOZ_ASSERT(socketBase); - - if (mEvent == CONNECT_SUCCESS) { - socketBase->NotifySuccess(); - } else if (mEvent == CONNECT_ERROR) { - socketBase->NotifyError(); - } else if (mEvent == DISCONNECT) { - socketBase->NotifyDisconnect(); - } - - return NS_OK; -} - -// -// SocketRequestClosingTask -// - -SocketRequestClosingTask::SocketRequestClosingTask(SocketIOBase* aIO) - : SocketTask<SocketIOBase>(aIO) -{ - MOZ_COUNT_CTOR(SocketRequestClosingTask); -} - -SocketRequestClosingTask::~SocketRequestClosingTask() -{ - MOZ_COUNT_DTOR(SocketRequestClosingTask); -} - -NS_IMETHODIMP -SocketRequestClosingTask::Run() -{ - SocketIOBase* io = SocketTask<SocketIOBase>::GetIO(); - - MOZ_ASSERT(io->IsConsumerThread()); - - if (NS_WARN_IF(io->IsShutdownOnConsumerThread())) { - // Since we've already explicitly closed and the close - // happened before this, this isn't really an error. - return NS_OK; - } - - SocketBase* socketBase = io->GetSocketBase(); - MOZ_ASSERT(socketBase); - - socketBase->Close(); - - return NS_OK; -} - -// -// SocketDeleteInstanceTask -// - -SocketDeleteInstanceTask::SocketDeleteInstanceTask(SocketIOBase* aIO) - : mIO(aIO) -{ - MOZ_COUNT_CTOR(SocketDeleteInstanceTask); -} - -SocketDeleteInstanceTask::~SocketDeleteInstanceTask() -{ - MOZ_COUNT_DTOR(SocketDeleteInstanceTask); -} - -NS_IMETHODIMP -SocketDeleteInstanceTask::Run() -{ - mIO.reset(); // delete instance - return NS_OK; -} - -// -// SocketIOShutdownTask -// - -SocketIOShutdownTask::SocketIOShutdownTask(SocketIOBase* aIO) - : SocketIOTask<SocketIOBase>(aIO) -{ - MOZ_COUNT_CTOR(SocketIOShutdownTask); -} - -SocketIOShutdownTask::~SocketIOShutdownTask() -{ - MOZ_COUNT_DTOR(SocketIOShutdownTask); -} - -NS_IMETHODIMP -SocketIOShutdownTask::Run() -{ - SocketIOBase* io = SocketIOTask<SocketIOBase>::GetIO(); - - MOZ_ASSERT(!io->IsConsumerThread()); - MOZ_ASSERT(!io->IsShutdownOnIOThread()); - - // At this point, there should be no new events on the I/O thread - // after this one with the possible exception of an accept task, - // which ShutdownOnIOThread will cancel for us. We are now fully - // shut down, so we can send a message to the consumer thread to - // delete |io| safely knowing that it's not reference any longer. - io->ShutdownOnIOThread(); - io->GetConsumerThread()->PostTask( - MakeAndAddRef<SocketDeleteInstanceTask>(io)); - return NS_OK; -} - -} -} diff --git a/ipc/unixsocket/SocketBase.h b/ipc/unixsocket/SocketBase.h deleted file mode 100644 index 191567fdb..000000000 --- a/ipc/unixsocket/SocketBase.h +++ /dev/null @@ -1,585 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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/. - */ - -#ifndef mozilla_ipc_SocketBase_h -#define mozilla_ipc_SocketBase_h - -#include "base/message_loop.h" -#include "mozilla/UniquePtr.h" - -namespace mozilla { -namespace ipc { - -// -// UnixSocketBuffer -// - -/** - * |UnixSocketBuffer| implements a FIFO buffer that stores raw socket - * data, either for sending on a socket or received from a socket. - */ -class UnixSocketBuffer -{ -public: - virtual ~UnixSocketBuffer(); - - const uint8_t* GetData() const - { - return mData + mOffset; - } - - size_t GetSize() const - { - return mSize - mOffset; - } - - const uint8_t* Consume(size_t aLen); - - nsresult Read(void* aValue, size_t aLen); - - nsresult Read(int8_t& aValue) - { - return Read(&aValue, sizeof(aValue)); - } - - nsresult Read(uint8_t& aValue) - { - return Read(&aValue, sizeof(aValue)); - } - - nsresult Read(int16_t& aValue) - { - return Read(&aValue, sizeof(aValue)); - } - - nsresult Read(uint16_t& aValue) - { - return Read(&aValue, sizeof(aValue)); - } - - nsresult Read(int32_t& aValue) - { - return Read(&aValue, sizeof(aValue)); - } - - nsresult Read(uint32_t& aValue) - { - return Read(&aValue, sizeof(aValue)); - } - - nsresult Read(int64_t& aValue) - { - return Read(&aValue, sizeof(aValue)); - } - - nsresult Read(uint64_t& aValue) - { - return Read(&aValue, sizeof(aValue)); - } - - nsresult Read(float& aValue) - { - return Read(&aValue, sizeof(aValue)); - } - - nsresult Read(double& aValue) - { - return Read(&aValue, sizeof(aValue)); - } - - uint8_t* Append(size_t aLen); - - nsresult Write(const void* aValue, size_t aLen); - - nsresult Write(int8_t aValue) - { - return Write(&aValue, sizeof(aValue)); - } - - nsresult Write(uint8_t aValue) - { - return Write(&aValue, sizeof(aValue)); - } - - nsresult Write(int16_t aValue) - { - return Write(&aValue, sizeof(aValue)); - } - - nsresult Write(uint16_t aValue) - { - return Write(&aValue, sizeof(aValue)); - } - - nsresult Write(int32_t aValue) - { - return Write(&aValue, sizeof(aValue)); - } - - nsresult Write(uint32_t aValue) - { - return Write(&aValue, sizeof(aValue)); - } - - nsresult Write(int64_t aValue) - { - return Write(&aValue, sizeof(aValue)); - } - - nsresult Write(uint64_t aValue) - { - return Write(&aValue, sizeof(aValue)); - } - - nsresult Write(float aValue) - { - return Write(&aValue, sizeof(aValue)); - } - - nsresult Write(double aValue) - { - return Write(&aValue, sizeof(aValue)); - } - -protected: - UnixSocketBuffer(); - - /** - * Sets the raw memory. The caller is responsible for freeing - * this memory. - * - * @param aData A pointer to the buffer's raw memory. - * @param aOffset The start of valid bytes in |aData|. - * @param aSize The number of valid bytes in |aData|. - * @param aAvailableSpace The number of bytes in |aData|. - */ - void ResetBuffer(uint8_t* aData, - size_t aOffset, size_t aSize, size_t aAvailableSpace) - { - MOZ_ASSERT(aData || !aAvailableSpace); - MOZ_ASSERT((aOffset + aSize) <= aAvailableSpace); - - mOffset = aOffset; - mSize = aSize; - mAvailableSpace = aAvailableSpace; - mData = aData; - } - - /** - * Retrieves the memory buffer. - * - * @return A pointer to the buffer's raw memory. - */ - uint8_t* GetBuffer() - { - return mData; - } - - size_t GetLeadingSpace() const - { - return mOffset; - } - - size_t GetTrailingSpace() const - { - return mAvailableSpace - mSize; - } - - size_t GetAvailableSpace() const - { - return mAvailableSpace; - } - - void* GetTrailingBytes() - { - return mData + mSize; - } - - uint8_t* GetData(size_t aOffset) - { - MOZ_ASSERT(aOffset <= mSize); - - return mData + aOffset; - } - - void SetRange(size_t aOffset, size_t aSize) - { - MOZ_ASSERT((aOffset + aSize) <= mAvailableSpace); - - mOffset = aOffset; - mSize = mOffset + aSize; - } - - void CleanupLeadingSpace(); - -private: - size_t mSize; - size_t mOffset; - size_t mAvailableSpace; - uint8_t* mData; -}; - -// -// UnixSocketIOBuffer -// - -/** - * |UnixSocketIOBuffer| is a |UnixSocketBuffer| that supports being - * received on a socket or being send on a socket. Network protocols - * might differ in their exact usage of Unix socket functions and - * |UnixSocketIOBuffer| provides a protocol-neutral interface. - */ -class UnixSocketIOBuffer : public UnixSocketBuffer -{ -public: - UnixSocketIOBuffer(); - virtual ~UnixSocketIOBuffer(); - - /** - * Receives data from aFd at the end of the buffer. The returned value - * is the number of newly received bytes, or 0 if the peer shut down - * its connection, or a negative value on errors. - */ - virtual ssize_t Receive(int aFd) = 0; - - /** - * Sends data to aFd from the beginning of the buffer. The returned value - * is the number of bytes written, or a negative value on error. - */ - virtual ssize_t Send(int aFd) = 0; -}; - -// -// UnixSocketRawData -// - -class UnixSocketRawData final : public UnixSocketIOBuffer -{ -public: - /** - * This constructor copies aData of aSize bytes length into the - * new instance of |UnixSocketRawData|. - * - * @param aData The buffer to copy. - * @param aSize The number of bytes in |aData|. - */ - UnixSocketRawData(const void* aData, size_t aSize); - - /** - * This constructor takes ownership of the data in aData. The - * data is assumed to be aSize bytes in length. - * - * @param aData The buffer to take ownership of. - * @param aSize The number of bytes in |aData|. - */ - UnixSocketRawData(UniquePtr<uint8_t[]> aData, size_t aSize); - - /** - * This constructor reserves aSize bytes of space. Currently - * it's only possible to fill this buffer by calling |Receive|. - * - * @param aSize The number of bytes to allocate. - */ - UnixSocketRawData(size_t aSize); - - /** - * The destructor releases the buffer's raw memory. - */ - ~UnixSocketRawData(); - - /** - * Receives data from aFd at the end of the buffer. The returned value - * is the number of newly received bytes, or 0 if the peer shut down - * its connection, or a negative value on errors. - */ - ssize_t Receive(int aFd) override; - - /** - * Sends data to aFd from the beginning of the buffer. The returned value - * is the number of bytes written, or a negative value on error. - */ - ssize_t Send(int aFd) override; -}; - -enum SocketConnectionStatus { - SOCKET_DISCONNECTED = 0, - SOCKET_LISTENING = 1, - SOCKET_CONNECTING = 2, - SOCKET_CONNECTED = 3 -}; - -// -// SocketBase -// - -class SocketBase -{ -public: - NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SocketBase) - - SocketConnectionStatus GetConnectionStatus() const; - - int GetSuggestedConnectDelayMs() const; - - /** - * Queues the internal representation of socket for deletion. Can be called - * from consumer thread. - */ - virtual void Close() = 0; - - /** - * Callback for socket connect/accept success. Called after connect/accept has - * finished. Will be run on consumer thread before any reads take place. - */ - virtual void OnConnectSuccess() = 0; - - /** - * Callback for socket connect/accept error. Will be run on consumer thread. - */ - virtual void OnConnectError() = 0; - - /** - * Callback for socket disconnect. Will be run on consumer thread. - */ - virtual void OnDisconnect() = 0; - - /** - * Called by implementation to notify consumer of success. - */ - void NotifySuccess(); - - /** - * Called by implementation to notify consumer of error. - */ - void NotifyError(); - - /** - * Called by implementation to notify consumer of disconnect. - */ - void NotifyDisconnect(); - -protected: - SocketBase(); - virtual ~SocketBase(); - - void SetConnectionStatus(SocketConnectionStatus aConnectionStatus); - -private: - uint32_t CalculateConnectDelayMs() const; - - SocketConnectionStatus mConnectionStatus; - PRIntervalTime mConnectTimestamp; - uint32_t mConnectDelayMs; -}; - -// -// SocketIOBase -// - -/** - * |SocketIOBase| is a base class for Socket I/O classes that - * perform operations on the I/O thread. - */ -class SocketIOBase -{ -public: - virtual ~SocketIOBase(); - - /** - * Implemented by socket I/O classes to return the current instance of - * |SocketBase|. - * - * @return The current instance of |SocketBase| - */ - virtual SocketBase* GetSocketBase() = 0; - - /** - * Implemented by socket I/O classes to signal that the socket I/O class has - * been shut down. - * - * @return True if the socket I/O class has been shut down, false otherwise. - */ - virtual bool IsShutdownOnIOThread() const = 0; - - /** - * Implemented by socket I/O classes to signal that socket class has - * been shut down. - * - * @return True if the socket class has been shut down, false otherwise. - */ - virtual bool IsShutdownOnConsumerThread() const = 0; - - /** - * Signals to the socket I/O classes that it has been shut down. - */ - virtual void ShutdownOnIOThread() = 0; - - /** - * Signals to the socket I/O classes that the socket class has been - * shut down. - */ - virtual void ShutdownOnConsumerThread() = 0; - - /** - * Returns the consumer thread. - * - * @return A pointer to the consumer thread. - */ - MessageLoop* GetConsumerThread() const; - - /** - * @return True if the current thread is the consumer thread, or false - * otherwise. - */ - bool IsConsumerThread() const; - -protected: - SocketIOBase(MessageLoop* aConsumerLoop); - -private: - MessageLoop* mConsumerLoop; -}; - -// -// Socket tasks -// - -/* |SocketTask| is a task for sending a message from - * the I/O thread to the consumer thread. - */ -template <typename T> -class SocketTask : public CancelableRunnable -{ -public: - virtual ~SocketTask() - { } - - T* GetIO() const - { - return mIO; - } - -protected: - SocketTask(T* aIO) - : mIO(aIO) - { - MOZ_ASSERT(aIO); - } - -private: - T* mIO; -}; - -/** - * |SocketEventTask| reports the connection state on the - * I/O thread back to the consumer thread. - */ -class SocketEventTask final : public SocketTask<SocketIOBase> -{ -public: - enum SocketEvent { - CONNECT_SUCCESS, - CONNECT_ERROR, - DISCONNECT - }; - - SocketEventTask(SocketIOBase* aIO, SocketEvent aEvent); - ~SocketEventTask(); - - NS_IMETHOD Run() override; - -private: - SocketEvent mEvent; -}; - -/** - * |SocketRequestClosingTask| closes an instance of |SocketBase| - * on the consumer thread. - */ -class SocketRequestClosingTask final : public SocketTask<SocketIOBase> -{ -public: - SocketRequestClosingTask(SocketIOBase* aIO); - ~SocketRequestClosingTask(); - - NS_IMETHOD Run() override; -}; - -/** - * |SocketDeleteInstanceTask| deletes an object on the consumer thread. - */ -class SocketDeleteInstanceTask final : public Runnable -{ -public: - SocketDeleteInstanceTask(SocketIOBase* aIO); - ~SocketDeleteInstanceTask(); - - NS_IMETHOD Run() override; - -private: - UniquePtr<SocketIOBase> mIO; -}; - -// -// Socket I/O tasks -// - -/* |SocketIOTask| holds a reference to a Socket I/O object. It's - * supposed to run on the I/O thread. - */ -template<typename Tio> -class SocketIOTask : public CancelableRunnable -{ -public: - virtual ~SocketIOTask() - { } - - Tio* GetIO() const - { - return mIO; - } - - nsresult Cancel() override - { - mIO = nullptr; - return NS_OK; - } - - bool IsCanceled() const - { - return !mIO; - } - -protected: - SocketIOTask(Tio* aIO) - : mIO(aIO) - { - MOZ_ASSERT(mIO); - } - -private: - Tio* mIO; -}; - -/** - * |SocketIOShutdownTask| signals shutdown to the socket I/O class on - * the I/O thread and sends it to the consumer thread for destruction. - */ -class SocketIOShutdownTask final : public SocketIOTask<SocketIOBase> -{ -public: - SocketIOShutdownTask(SocketIOBase* aIO); - ~SocketIOShutdownTask(); - - NS_IMETHOD Run() override; -}; - -} -} - -#endif diff --git a/ipc/unixsocket/StreamSocket.cpp b/ipc/unixsocket/StreamSocket.cpp deleted file mode 100644 index 04c37e554..000000000 --- a/ipc/unixsocket/StreamSocket.cpp +++ /dev/null @@ -1,482 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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 "StreamSocket.h" -#include <fcntl.h> -#include "mozilla/RefPtr.h" -#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, MOZ_COUNT_DTOR -#include "nsXULAppAPI.h" -#include "StreamSocketConsumer.h" -#include "UnixSocketConnector.h" - -static const size_t MAX_READ_SIZE = 1 << 16; - -namespace mozilla { -namespace ipc { - -// -// StreamSocketIO -// - -class StreamSocketIO final : public ConnectionOrientedSocketIO -{ -public: - class ConnectTask; - class DelayedConnectTask; - class ReceiveTask; - - StreamSocketIO(MessageLoop* aConsumerLoop, - MessageLoop* aIOLoop, - StreamSocket* aStreamSocket, - UnixSocketConnector* aConnector); - StreamSocketIO(MessageLoop* aConsumerLoop, - MessageLoop* aIOLoop, - int aFd, ConnectionStatus aConnectionStatus, - StreamSocket* aStreamSocket, - UnixSocketConnector* aConnector); - ~StreamSocketIO(); - - StreamSocket* GetStreamSocket(); - DataSocket* GetDataSocket(); - - // Delayed-task handling - // - - void SetDelayedConnectTask(CancelableRunnable* aTask); - void ClearDelayedConnectTask(); - void CancelDelayedConnectTask(); - - // Methods for |DataSocket| - // - - nsresult QueryReceiveBuffer(UnixSocketIOBuffer** aBuffer) override; - void ConsumeBuffer() override; - void DiscardBuffer() override; - - // Methods for |SocketIOBase| - // - - SocketBase* GetSocketBase() override; - - bool IsShutdownOnConsumerThread() const override; - bool IsShutdownOnIOThread() const override; - - void ShutdownOnConsumerThread() override; - void ShutdownOnIOThread() override; - -private: - /** - * Consumer pointer. Non-thread-safe pointer, so should only be manipulated - * directly from consumer thread. All non-consumer-thread accesses should - * happen with mIO as container. - */ - StreamSocket* mStreamSocket; - - /** - * If true, do not requeue whatever task we're running - */ - bool mShuttingDownOnIOThread; - - /** - * Task member for delayed connect task. Should only be access on consumer - * thread. - */ - CancelableRunnable* mDelayedConnectTask; - - /** - * I/O buffer for received data - */ - UniquePtr<UnixSocketRawData> mBuffer; -}; - -StreamSocketIO::StreamSocketIO(MessageLoop* aConsumerLoop, - MessageLoop* aIOLoop, - StreamSocket* aStreamSocket, - UnixSocketConnector* aConnector) - : ConnectionOrientedSocketIO(aConsumerLoop, aIOLoop, aConnector) - , mStreamSocket(aStreamSocket) - , mShuttingDownOnIOThread(false) - , mDelayedConnectTask(nullptr) -{ - MOZ_ASSERT(mStreamSocket); - - MOZ_COUNT_CTOR_INHERITED(StreamSocketIO, ConnectionOrientedSocketIO); -} - -StreamSocketIO::StreamSocketIO(MessageLoop* aConsumerLoop, - MessageLoop* aIOLoop, - int aFd, ConnectionStatus aConnectionStatus, - StreamSocket* aStreamSocket, - UnixSocketConnector* aConnector) - : ConnectionOrientedSocketIO(aConsumerLoop, - aIOLoop, - aFd, - aConnectionStatus, - aConnector) - , mStreamSocket(aStreamSocket) - , mShuttingDownOnIOThread(false) - , mDelayedConnectTask(nullptr) -{ - MOZ_ASSERT(mStreamSocket); - - MOZ_COUNT_CTOR_INHERITED(StreamSocketIO, ConnectionOrientedSocketIO); -} - -StreamSocketIO::~StreamSocketIO() -{ - MOZ_ASSERT(IsConsumerThread()); - MOZ_ASSERT(IsShutdownOnConsumerThread()); - - MOZ_COUNT_DTOR_INHERITED(StreamSocketIO, ConnectionOrientedSocketIO); -} - -StreamSocket* -StreamSocketIO::GetStreamSocket() -{ - return mStreamSocket; -} - -DataSocket* -StreamSocketIO::GetDataSocket() -{ - return GetStreamSocket(); -} - -void -StreamSocketIO::SetDelayedConnectTask(CancelableRunnable* aTask) -{ - MOZ_ASSERT(IsConsumerThread()); - - mDelayedConnectTask = aTask; -} - -void -StreamSocketIO::ClearDelayedConnectTask() -{ - MOZ_ASSERT(IsConsumerThread()); - - mDelayedConnectTask = nullptr; -} - -void -StreamSocketIO::CancelDelayedConnectTask() -{ - MOZ_ASSERT(IsConsumerThread()); - - if (!mDelayedConnectTask) { - return; - } - - mDelayedConnectTask->Cancel(); - ClearDelayedConnectTask(); -} - -// |DataSocketIO| - -nsresult -StreamSocketIO::QueryReceiveBuffer(UnixSocketIOBuffer** aBuffer) -{ - MOZ_ASSERT(aBuffer); - - if (!mBuffer) { - mBuffer = MakeUnique<UnixSocketRawData>(MAX_READ_SIZE); - } - *aBuffer = mBuffer.get(); - - return NS_OK; -} - -/** - * |ReceiveTask| transfers data received on the I/O thread - * to an instance of |StreamSocket| on the consumer thread. - */ -class StreamSocketIO::ReceiveTask final : public SocketTask<StreamSocketIO> -{ -public: - ReceiveTask(StreamSocketIO* aIO, UnixSocketBuffer* aBuffer) - : SocketTask<StreamSocketIO>(aIO) - , mBuffer(aBuffer) - { - MOZ_COUNT_CTOR(ReceiveTask); - } - - ~ReceiveTask() - { - MOZ_COUNT_DTOR(ReceiveTask); - } - - NS_IMETHOD Run() override - { - StreamSocketIO* io = SocketTask<StreamSocketIO>::GetIO(); - - MOZ_ASSERT(io->IsConsumerThread()); - - if (NS_WARN_IF(io->IsShutdownOnConsumerThread())) { - // Since we've already explicitly closed and the close - // happened before this, this isn't really an error. - return NS_OK; - } - - StreamSocket* streamSocket = io->GetStreamSocket(); - MOZ_ASSERT(streamSocket); - - streamSocket->ReceiveSocketData(mBuffer); - - return NS_OK; - } - -private: - UniquePtr<UnixSocketBuffer> mBuffer; -}; - -void -StreamSocketIO::ConsumeBuffer() -{ - GetConsumerThread()->PostTask( - MakeAndAddRef<ReceiveTask>(this, mBuffer.release())); -} - -void -StreamSocketIO::DiscardBuffer() -{ - // Nothing to do. -} - -// |SocketIOBase| - -SocketBase* -StreamSocketIO::GetSocketBase() -{ - return GetDataSocket(); -} - -bool -StreamSocketIO::IsShutdownOnConsumerThread() const -{ - MOZ_ASSERT(IsConsumerThread()); - - return mStreamSocket == nullptr; -} - -bool -StreamSocketIO::IsShutdownOnIOThread() const -{ - return mShuttingDownOnIOThread; -} - -void -StreamSocketIO::ShutdownOnConsumerThread() -{ - MOZ_ASSERT(IsConsumerThread()); - MOZ_ASSERT(!IsShutdownOnConsumerThread()); - - mStreamSocket = nullptr; -} - -void -StreamSocketIO::ShutdownOnIOThread() -{ - MOZ_ASSERT(!IsConsumerThread()); - MOZ_ASSERT(!mShuttingDownOnIOThread); - - Close(); // will also remove fd from I/O loop - mShuttingDownOnIOThread = true; -} - -// -// Socket tasks -// - -class StreamSocketIO::ConnectTask final : public SocketIOTask<StreamSocketIO> -{ -public: - ConnectTask(StreamSocketIO* aIO) - : SocketIOTask<StreamSocketIO>(aIO) - { - MOZ_COUNT_CTOR(ReceiveTask); - } - - ~ConnectTask() - { - MOZ_COUNT_DTOR(ReceiveTask); - } - - NS_IMETHOD Run() override - { - MOZ_ASSERT(!GetIO()->IsConsumerThread()); - MOZ_ASSERT(!IsCanceled()); - - GetIO()->Connect(); - - return NS_OK; - } -}; - -class StreamSocketIO::DelayedConnectTask final - : public SocketIOTask<StreamSocketIO> -{ -public: - DelayedConnectTask(StreamSocketIO* aIO) - : SocketIOTask<StreamSocketIO>(aIO) - { - MOZ_COUNT_CTOR(DelayedConnectTask); - } - - ~DelayedConnectTask() - { - MOZ_COUNT_DTOR(DelayedConnectTask); - } - - NS_IMETHOD Run() override - { - MOZ_ASSERT(GetIO()->IsConsumerThread()); - - if (IsCanceled()) { - return NS_OK; - } - - StreamSocketIO* io = GetIO(); - if (io->IsShutdownOnConsumerThread()) { - return NS_OK; - } - - io->ClearDelayedConnectTask(); - io->GetIOLoop()->PostTask(MakeAndAddRef<ConnectTask>(io)); - - return NS_OK; - } -}; - -// -// StreamSocket -// - -StreamSocket::StreamSocket(StreamSocketConsumer* aConsumer, int aIndex) - : mIO(nullptr) - , mConsumer(aConsumer) - , mIndex(aIndex) -{ - MOZ_ASSERT(mConsumer); - - MOZ_COUNT_CTOR_INHERITED(StreamSocket, ConnectionOrientedSocket); -} - -StreamSocket::~StreamSocket() -{ - MOZ_ASSERT(!mIO); - - MOZ_COUNT_DTOR_INHERITED(StreamSocket, ConnectionOrientedSocket); -} - -void -StreamSocket::ReceiveSocketData(UniquePtr<UnixSocketBuffer>& aBuffer) -{ - mConsumer->ReceiveSocketData(mIndex, aBuffer); -} - -nsresult -StreamSocket::Connect(UnixSocketConnector* aConnector, int aDelayMs, - MessageLoop* aConsumerLoop, MessageLoop* aIOLoop) -{ - MOZ_ASSERT(!mIO); - - mIO = new StreamSocketIO(aConsumerLoop, aIOLoop, this, aConnector); - SetConnectionStatus(SOCKET_CONNECTING); - - if (aDelayMs > 0) { - RefPtr<StreamSocketIO::DelayedConnectTask> connectTask = - MakeAndAddRef<StreamSocketIO::DelayedConnectTask>(mIO); - mIO->SetDelayedConnectTask(connectTask); - MessageLoop::current()->PostDelayedTask(connectTask.forget(), aDelayMs); - } else { - aIOLoop->PostTask(MakeAndAddRef<StreamSocketIO::ConnectTask>(mIO)); - } - - return NS_OK; -} - -nsresult -StreamSocket::Connect(UnixSocketConnector* aConnector, int aDelayMs) -{ - return Connect(aConnector, aDelayMs, - MessageLoop::current(), XRE_GetIOMessageLoop()); -} - -// |ConnectionOrientedSocket| - -nsresult -StreamSocket::PrepareAccept(UnixSocketConnector* aConnector, - MessageLoop* aConsumerLoop, - MessageLoop* aIOLoop, - ConnectionOrientedSocketIO*& aIO) -{ - MOZ_ASSERT(!mIO); - MOZ_ASSERT(aConnector); - - SetConnectionStatus(SOCKET_CONNECTING); - - mIO = new StreamSocketIO(aConsumerLoop, aIOLoop, - -1, UnixSocketWatcher::SOCKET_IS_CONNECTING, - this, aConnector); - aIO = mIO; - - return NS_OK; -} - -// |DataSocket| - -void -StreamSocket::SendSocketData(UnixSocketIOBuffer* aBuffer) -{ - MOZ_ASSERT(mIO); - MOZ_ASSERT(mIO->IsConsumerThread()); - MOZ_ASSERT(!mIO->IsShutdownOnConsumerThread()); - - mIO->GetIOLoop()->PostTask( - MakeAndAddRef<SocketIOSendTask<StreamSocketIO, UnixSocketIOBuffer>>( - mIO, aBuffer)); -} - -// |SocketBase| - -void -StreamSocket::Close() -{ - MOZ_ASSERT(mIO); - MOZ_ASSERT(mIO->IsConsumerThread()); - - mIO->CancelDelayedConnectTask(); - - // From this point on, we consider |mIO| as being deleted. We sever - // the relationship here so any future calls to |Connect| will create - // a new I/O object. - mIO->ShutdownOnConsumerThread(); - mIO->GetIOLoop()->PostTask(MakeAndAddRef<SocketIOShutdownTask>(mIO)); - mIO = nullptr; - - NotifyDisconnect(); -} - -void -StreamSocket::OnConnectSuccess() -{ - mConsumer->OnConnectSuccess(mIndex); -} - -void -StreamSocket::OnConnectError() -{ - mConsumer->OnConnectError(mIndex); -} - -void -StreamSocket::OnDisconnect() -{ - mConsumer->OnDisconnect(mIndex); -} - -} // namespace ipc -} // namespace mozilla diff --git a/ipc/unixsocket/StreamSocket.h b/ipc/unixsocket/StreamSocket.h deleted file mode 100644 index cb732389f..000000000 --- a/ipc/unixsocket/StreamSocket.h +++ /dev/null @@ -1,95 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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/. */ - -#ifndef mozilla_ipc_streamsocket_h -#define mozilla_ipc_streamsocket_h - -#include "ConnectionOrientedSocket.h" - -class MessageLoop; - -namespace mozilla { -namespace ipc { - -class StreamSocketConsumer; -class StreamSocketIO; -class UnixSocketConnector; - -class StreamSocket final : public ConnectionOrientedSocket -{ -public: - /** - * Constructs an instance of |StreamSocket|. - * - * @param aConsumer The consumer for the socket. - * @param aIndex An arbitrary index. - */ - StreamSocket(StreamSocketConsumer* aConsumer, int aIndex); - - /** - * Method to be called whenever data is received. Consumer-thread only. - * - * @param aBuffer Data received from the socket. - */ - void ReceiveSocketData(UniquePtr<UnixSocketBuffer>& aBuffer); - - /** - * Starts a task on the socket that will try to connect to a socket in a - * non-blocking manner. - * - * @param aConnector Connector object for socket type specific functions - * @param aDelayMs Time delay in milliseconds. - * @param aConsumerLoop The socket's consumer thread. - * @param aIOLoop The socket's I/O thread. - * @return NS_OK on success, or an XPCOM error code otherwise. - */ - nsresult Connect(UnixSocketConnector* aConnector, int aDelayMs, - MessageLoop* aConsumerLoop, MessageLoop* aIOLoop); - - /** - * Starts a task on the socket that will try to connect to a socket in a - * non-blocking manner. - * - * @param aConnector Connector object for socket type specific functions - * @param aDelayMs Time delay in milliseconds. - * @return NS_OK on success, or an XPCOM error code otherwise. - */ - nsresult Connect(UnixSocketConnector* aConnector, int aDelayMs = 0); - - // Methods for |ConnectionOrientedSocket| - // - - nsresult PrepareAccept(UnixSocketConnector* aConnector, - MessageLoop* aConsumerLoop, - MessageLoop* aIOLoop, - ConnectionOrientedSocketIO*& aIO) override; - - // Methods for |DataSocket| - // - - void SendSocketData(UnixSocketIOBuffer* aBuffer) override; - - // Methods for |SocketBase| - // - - void Close() override; - void OnConnectSuccess() override; - void OnConnectError() override; - void OnDisconnect() override; - -protected: - virtual ~StreamSocket(); - -private: - StreamSocketIO* mIO; - StreamSocketConsumer* mConsumer; - int mIndex; -}; - -} // namespace ipc -} // namepsace mozilla - -#endif // mozilla_ipc_streamsocket_h diff --git a/ipc/unixsocket/StreamSocketConsumer.cpp b/ipc/unixsocket/StreamSocketConsumer.cpp deleted file mode 100644 index bac9c1fe7..000000000 --- a/ipc/unixsocket/StreamSocketConsumer.cpp +++ /dev/null @@ -1,20 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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 "StreamSocketConsumer.h" - -namespace mozilla { -namespace ipc { - -// -// StreamSocketConsumer -// - -StreamSocketConsumer::~StreamSocketConsumer() -{ } - -} -} diff --git a/ipc/unixsocket/StreamSocketConsumer.h b/ipc/unixsocket/StreamSocketConsumer.h deleted file mode 100644 index d1f8c3d5b..000000000 --- a/ipc/unixsocket/StreamSocketConsumer.h +++ /dev/null @@ -1,60 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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/. */ - -#ifndef mozilla_ipc_streamsocketconsumer_h -#define mozilla_ipc_streamsocketconsumer_h - -#include "mozilla/UniquePtr.h" - -namespace mozilla { -namespace ipc { - -class UnixSocketBuffer; - -/** - * |StreamSocketConsumer| handles socket events and received data. - */ -class StreamSocketConsumer -{ -public: - /** - * Method to be called whenever data is received. Consumer-thread only. - * - * @param aIndex The index that has been given to the stream socket. - * @param aBuffer Data received from the socket. - */ - virtual void ReceiveSocketData(int aIndex, - UniquePtr<UnixSocketBuffer>& aBuffer) = 0; - - /** - * Callback for socket success. Consumer-thread only. - * - * @param aIndex The index that has been given to the stream socket. - */ - virtual void OnConnectSuccess(int aIndex) = 0; - - /** - * Callback for socket errors. Consumer-thread only. - * - * @param aIndex The index that has been given to the stream socket. - */ - virtual void OnConnectError(int aIndex) = 0; - - /** - * Callback for socket disconnect. Consumer-thread only. - * - * @param aIndex The index that has been given to the stream socket. - */ - virtual void OnDisconnect(int aIndex) = 0; - -protected: - virtual ~StreamSocketConsumer(); -}; - -} -} - -#endif diff --git a/ipc/unixsocket/UnixSocketConnector.cpp b/ipc/unixsocket/UnixSocketConnector.cpp deleted file mode 100644 index eb38ff6de..000000000 --- a/ipc/unixsocket/UnixSocketConnector.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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 "UnixSocketConnector.h" -#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, MOZ_COUNT_DTOR - -namespace mozilla { -namespace ipc { - -UnixSocketConnector::UnixSocketConnector() -{ - MOZ_COUNT_CTOR(UnixSocketConnector); -} - -UnixSocketConnector::~UnixSocketConnector() -{ - MOZ_COUNT_DTOR(UnixSocketConnector); -} - -nsresult -UnixSocketConnector::Duplicate(UniquePtr<UnixSocketConnector>& aConnector) -{ - UnixSocketConnector* connectorPtr; - auto rv = Duplicate(connectorPtr); - if (NS_FAILED(rv)) { - return rv; - } - - aConnector = Move(UniquePtr<UnixSocketConnector>(connectorPtr)); - - return NS_OK; -} - -} -} diff --git a/ipc/unixsocket/UnixSocketConnector.h b/ipc/unixsocket/UnixSocketConnector.h deleted file mode 100644 index 21d2c7860..000000000 --- a/ipc/unixsocket/UnixSocketConnector.h +++ /dev/null @@ -1,102 +0,0 @@ -/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ -/* vim: set ts=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/. */ - -#ifndef mozilla_ipc_unixsocketconnector_h -#define mozilla_ipc_unixsocketconnector_h - -#include <sys/socket.h> -#include "mozilla/ipc/UnixSocketWatcher.h" -#include "nsString.h" - -namespace mozilla { -namespace ipc { - -/** - * |UnixSocketConnector| defines the socket creation and connection/listening - * functions for |UnixSocketConsumer|, et al. Due to the fact that socket setup - * can vary between protocols (Unix sockets, TCP sockets, Bluetooth sockets, etc), - * this allows the user to create whatever connection mechanism they need while - * still depending on libevent for non-blocking communication handling. - */ -class UnixSocketConnector -{ -public: - virtual ~UnixSocketConnector(); - - /** - * Converts an address to a human-readable string. - * - * @param aAddress A socket address - * @param aAddressLength The number of valid bytes in |aAddress| - * @param[out] aAddressString The resulting string - * @return NS_OK on success, or an XPCOM error code otherwise. - */ - virtual nsresult ConvertAddressToString(const struct sockaddr& aAddress, - socklen_t aAddressLength, - nsACString& aAddressString) = 0; - - /** - * Creates a listening socket. I/O thread only. - * - * @param[out] aAddress The listening socket's address - * @param[out] aAddressLength The number of valid bytes in |aAddress| - * @param[out] aListenFd The socket's file descriptor - * @return NS_OK on success, or an XPCOM error code otherwise. - */ - virtual nsresult CreateListenSocket(struct sockaddr* aAddress, - socklen_t* aAddressLength, - int& aListenFd) = 0; - - /** - * Accepts a stream socket from a listening socket. I/O thread only. - * - * @param aListenFd The listening socket - * @param[out] aAddress Returns the stream socket's address - * @param[out] aAddressLength Returns the number of valid bytes in |aAddress| - * @param[out] aStreamFd The stream socket's file descriptor - * @return NS_OK on success, or an XPCOM error code otherwise. - */ - virtual nsresult AcceptStreamSocket(int aListenFd, - struct sockaddr* aAddress, - socklen_t* aAddressLen, - int& aStreamFd) = 0; - - /** - * Creates a stream socket. I/O thread only. - * - * @param[in|out] aAddress The stream socket's address - * @param[in|out] aAddressLength The number of valid bytes in |aAddress| - * @param[out] aStreamFd The socket's file descriptor - * @return NS_OK on success, or an XPCOM error code otherwise. - */ - virtual nsresult CreateStreamSocket(struct sockaddr* aAddress, - socklen_t* aAddressLength, - int& aStreamFd) = 0; - - /** - * Copies the instance of |UnixSocketConnector|. I/O thread only. - * - * @param[in] aConnector Returns a new instance of the connector class - * @return NS_OK on success, or an XPCOM error code otherwise - */ - virtual nsresult Duplicate(UnixSocketConnector*& aConnector) = 0; - - /** - * Copies the instance of |UnixSocketConnector|. I/O thread only. - * - * @param[in] aConnector Returns a new instance of the connector class - * @return NS_OK on success, or an XPCOM error code otherwise - */ - nsresult Duplicate(UniquePtr<UnixSocketConnector>& aConnector); - -protected: - UnixSocketConnector(); -}; - -} -} - -#endif diff --git a/ipc/unixsocket/moz.build b/ipc/unixsocket/moz.build deleted file mode 100644 index 523aac3cb..000000000 --- a/ipc/unixsocket/moz.build +++ /dev/null @@ -1,31 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# 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/. - -EXPORTS.mozilla.ipc += [ - 'ConnectionOrientedSocket.h', - 'DataSocket.h', - 'ListenSocket.h', - 'ListenSocketConsumer.h', - 'SocketBase.h', - 'StreamSocket.h', - 'StreamSocketConsumer.h', - 'UnixSocketConnector.h' -] - -SOURCES += [ - 'ConnectionOrientedSocket.cpp', - 'DataSocket.cpp', - 'ListenSocket.cpp', - 'ListenSocketConsumer.cpp', - 'SocketBase.cpp', - 'StreamSocket.cpp', - 'StreamSocketConsumer.cpp', - 'UnixSocketConnector.cpp' -] - -include('/ipc/chromium/chromium-config.mozbuild') - -FINAL_LIBRARY = 'xul' |