summaryrefslogtreecommitdiffstats
path: root/netwerk/system/linux
diff options
context:
space:
mode:
Diffstat (limited to 'netwerk/system/linux')
-rw-r--r--netwerk/system/linux/moz.build16
-rw-r--r--netwerk/system/linux/nsNetworkLinkService.cpp211
-rw-r--r--netwerk/system/linux/nsNetworkLinkService.h47
3 files changed, 274 insertions, 0 deletions
diff --git a/netwerk/system/linux/moz.build b/netwerk/system/linux/moz.build
new file mode 100644
index 0000000000..8ddc517c3e
--- /dev/null
+++ b/netwerk/system/linux/moz.build
@@ -0,0 +1,16 @@
+# -*- 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/.
+
+if CONFIG["OS_ARCH"] == "Linux":
+ SOURCES += [
+ "nsNetworkLinkService.cpp",
+ ]
+
+LOCAL_INCLUDES += [
+ "/netwerk/base",
+]
+
+FINAL_LIBRARY = "xul"
diff --git a/netwerk/system/linux/nsNetworkLinkService.cpp b/netwerk/system/linux/nsNetworkLinkService.cpp
new file mode 100644
index 0000000000..363b058eed
--- /dev/null
+++ b/netwerk/system/linux/nsNetworkLinkService.cpp
@@ -0,0 +1,211 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set et sw=2 ts=4: */
+/* 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 "nsIObserverService.h"
+#include "nsNetworkLinkService.h"
+#include "nsString.h"
+#include "mozilla/Logging.h"
+#include "nsNetAddr.h"
+
+#include "mozilla/StaticPrefs_network.h"
+#include "mozilla/Services.h"
+
+using namespace mozilla;
+
+static LazyLogModule gNotifyAddrLog("nsNetworkLinkService");
+#define LOG(args) MOZ_LOG(gNotifyAddrLog, mozilla::LogLevel::Debug, args)
+
+NS_IMPL_ISUPPORTS(nsNetworkLinkService, nsINetworkLinkService, nsIObserver)
+
+nsNetworkLinkService::nsNetworkLinkService() : mStatusIsKnown(false) {}
+
+NS_IMETHODIMP
+nsNetworkLinkService::GetIsLinkUp(bool* aIsUp) {
+ if (!mNetlinkSvc) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+
+ mNetlinkSvc->GetIsLinkUp(aIsUp);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsNetworkLinkService::GetLinkStatusKnown(bool* aIsKnown) {
+ *aIsKnown = mStatusIsKnown;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsNetworkLinkService::GetLinkType(uint32_t* aLinkType) {
+ NS_ENSURE_ARG_POINTER(aLinkType);
+
+ // XXX This function has not yet been implemented for this platform
+ *aLinkType = nsINetworkLinkService::LINK_TYPE_UNKNOWN;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsNetworkLinkService::GetNetworkID(nsACString& aNetworkID) {
+ if (!mNetlinkSvc) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+
+ mNetlinkSvc->GetNetworkID(aNetworkID);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsNetworkLinkService::GetDnsSuffixList(nsTArray<nsCString>& aDnsSuffixList) {
+ if (!mNetlinkSvc) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+
+ return mNetlinkSvc->GetDnsSuffixList(aDnsSuffixList);
+}
+
+NS_IMETHODIMP
+nsNetworkLinkService::GetResolvers(nsTArray<RefPtr<nsINetAddr>>& aResolvers) {
+ nsTArray<mozilla::net::NetAddr> addresses;
+ nsresult rv = GetNativeResolvers(addresses);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ for (const auto& addr : addresses) {
+ aResolvers.AppendElement(MakeRefPtr<nsNetAddr>(&addr));
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsNetworkLinkService::GetNativeResolvers(
+ nsTArray<mozilla::net::NetAddr>& aResolvers) {
+ if (!mNetlinkSvc) {
+ return NS_ERROR_NOT_AVAILABLE;
+ }
+ return mNetlinkSvc->GetResolvers(aResolvers);
+}
+
+NS_IMETHODIMP
+nsNetworkLinkService::GetPlatformDNSIndications(
+ uint32_t* aPlatformDNSIndications) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsNetworkLinkService::Observe(nsISupports* subject, const char* topic,
+ const char16_t* data) {
+ if (!strcmp("xpcom-shutdown-threads", topic)) {
+ Shutdown();
+ }
+
+ return NS_OK;
+}
+
+nsresult nsNetworkLinkService::Init() {
+ nsCOMPtr<nsIObserverService> observerService =
+ mozilla::services::GetObserverService();
+ if (!observerService) {
+ return NS_ERROR_FAILURE;
+ }
+
+ nsresult rv;
+ rv = observerService->AddObserver(this, "xpcom-shutdown-threads", false);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ mNetlinkSvc = new mozilla::net::NetlinkService();
+ rv = mNetlinkSvc->Init(this);
+ if (NS_FAILED(rv)) {
+ mNetlinkSvc = nullptr;
+ LOG(("Cannot initialize NetlinkService [rv=0x%08" PRIx32 "]",
+ static_cast<uint32_t>(rv)));
+ return rv;
+ }
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ return NS_OK;
+}
+
+nsresult nsNetworkLinkService::Shutdown() {
+ // remove xpcom shutdown observer
+ nsCOMPtr<nsIObserverService> observerService =
+ mozilla::services::GetObserverService();
+ if (observerService) {
+ observerService->RemoveObserver(this, "xpcom-shutdown-threads");
+ }
+
+ if (mNetlinkSvc) {
+ mNetlinkSvc->Shutdown();
+ mNetlinkSvc = nullptr;
+ }
+
+ return NS_OK;
+}
+
+void nsNetworkLinkService::OnNetworkChanged() {
+ if (StaticPrefs::network_notify_changed()) {
+ RefPtr<nsNetworkLinkService> self = this;
+ NS_DispatchToMainThread(NS_NewRunnableFunction(
+ "nsNetworkLinkService::OnNetworkChanged", [self]() {
+ self->NotifyObservers(NS_NETWORK_LINK_TOPIC,
+ NS_NETWORK_LINK_DATA_CHANGED);
+ }));
+ }
+}
+
+void nsNetworkLinkService::OnNetworkIDChanged() {
+ RefPtr<nsNetworkLinkService> self = this;
+ NS_DispatchToMainThread(NS_NewRunnableFunction(
+ "nsNetworkLinkService::OnNetworkIDChanged", [self]() {
+ self->NotifyObservers(NS_NETWORK_ID_CHANGED_TOPIC, nullptr);
+ }));
+}
+
+void nsNetworkLinkService::OnLinkUp() {
+ RefPtr<nsNetworkLinkService> self = this;
+ NS_DispatchToMainThread(
+ NS_NewRunnableFunction("nsNetworkLinkService::OnLinkUp", [self]() {
+ self->NotifyObservers(NS_NETWORK_LINK_TOPIC, NS_NETWORK_LINK_DATA_UP);
+ }));
+}
+
+void nsNetworkLinkService::OnLinkDown() {
+ RefPtr<nsNetworkLinkService> self = this;
+ NS_DispatchToMainThread(
+ NS_NewRunnableFunction("nsNetworkLinkService::OnLinkDown", [self]() {
+ self->NotifyObservers(NS_NETWORK_LINK_TOPIC, NS_NETWORK_LINK_DATA_DOWN);
+ }));
+}
+
+void nsNetworkLinkService::OnLinkStatusKnown() { mStatusIsKnown = true; }
+
+void nsNetworkLinkService::OnDnsSuffixListUpdated() {
+ RefPtr<nsNetworkLinkService> self = this;
+ NS_DispatchToMainThread(NS_NewRunnableFunction(
+ "nsNetworkLinkService::OnDnsSuffixListUpdated", [self]() {
+ self->NotifyObservers(NS_DNS_SUFFIX_LIST_UPDATED_TOPIC, nullptr);
+ }));
+}
+
+/* Sends the given event. Assumes aTopic/aData never goes out of scope (static
+ * strings are ideal).
+ */
+void nsNetworkLinkService::NotifyObservers(const char* aTopic,
+ const char* aData) {
+ MOZ_ASSERT(NS_IsMainThread());
+
+ LOG(("nsNetworkLinkService::NotifyObservers: topic:%s data:%s\n", aTopic,
+ aData ? aData : ""));
+
+ nsCOMPtr<nsIObserverService> observerService =
+ mozilla::services::GetObserverService();
+
+ if (observerService) {
+ observerService->NotifyObservers(
+ static_cast<nsINetworkLinkService*>(this), aTopic,
+ aData ? NS_ConvertASCIItoUTF16(aData).get() : nullptr);
+ }
+}
diff --git a/netwerk/system/linux/nsNetworkLinkService.h b/netwerk/system/linux/nsNetworkLinkService.h
new file mode 100644
index 0000000000..d2c4521122
--- /dev/null
+++ b/netwerk/system/linux/nsNetworkLinkService.h
@@ -0,0 +1,47 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set et sw=2 ts=4: */
+/* 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 NSNETWORKLINKSERVICE_LINUX_H_
+#define NSNETWORKLINKSERVICE_LINUX_H_
+
+#include "nsINetworkLinkService.h"
+#include "nsIObserver.h"
+#include "../netlink/NetlinkService.h"
+#include "mozilla/RefPtr.h"
+#include "mozilla/Atomics.h"
+
+class nsNetworkLinkService : public nsINetworkLinkService,
+ public nsIObserver,
+ public mozilla::net::NetlinkServiceListener {
+ public:
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_NSINETWORKLINKSERVICE
+ NS_DECL_NSIOBSERVER
+
+ nsNetworkLinkService();
+ nsresult Init();
+
+ void OnNetworkChanged() override;
+ void OnNetworkIDChanged() override;
+ void OnLinkUp() override;
+ void OnLinkDown() override;
+ void OnLinkStatusKnown() override;
+ void OnDnsSuffixListUpdated() override;
+
+ private:
+ virtual ~nsNetworkLinkService() = default;
+
+ // Called when xpcom-shutdown-threads is received.
+ nsresult Shutdown();
+
+ // Sends the network event.
+ void NotifyObservers(const char* aTopic, const char* aData);
+
+ mozilla::Atomic<bool, mozilla::Relaxed> mStatusIsKnown;
+
+ RefPtr<mozilla::net::NetlinkService> mNetlinkSvc;
+};
+
+#endif /* NSNETWORKLINKSERVICE_LINUX_H_ */