diff options
Diffstat (limited to '')
-rw-r--r-- | netwerk/system/netlink/NetlinkService.h | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/netwerk/system/netlink/NetlinkService.h b/netwerk/system/netlink/NetlinkService.h new file mode 100644 index 0000000000..1de3992f47 --- /dev/null +++ b/netwerk/system/netlink/NetlinkService.h @@ -0,0 +1,168 @@ +/* -*- 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 NETLINKSERVICE_H_ +#define NETLINKSERVICE_H_ + +#include <netinet/in.h> + +#include "nsIRunnable.h" +#include "nsThreadUtils.h" +#include "nsCOMPtr.h" +#include "mozilla/Mutex.h" +#include "mozilla/TimeStamp.h" +#include "nsClassHashtable.h" +#include "mozilla/SHA1.h" +#include "mozilla/UniquePtr.h" +#include "nsTArray.h" +#include "mozilla/net/DNS.h" + +namespace mozilla { +namespace net { + +class NetlinkAddress; +class NetlinkNeighbor; +class NetlinkLink; +class NetlinkRoute; +class NetlinkMsg; + +class NetlinkServiceListener : public nsISupports { + public: + virtual void OnNetworkChanged() = 0; + virtual void OnNetworkIDChanged() = 0; + virtual void OnLinkUp() = 0; + virtual void OnLinkDown() = 0; + virtual void OnLinkStatusKnown() = 0; + virtual void OnDnsSuffixListUpdated() = 0; + + protected: + virtual ~NetlinkServiceListener() = default; +}; + +class NetlinkService : public nsIRunnable { + virtual ~NetlinkService(); + + public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIRUNNABLE + + NetlinkService(); + nsresult Init(NetlinkServiceListener* aListener); + nsresult Shutdown(); + void GetNetworkID(nsACString& aNetworkID); + void GetIsLinkUp(bool* aIsUp); + nsresult GetDnsSuffixList(nsTArray<nsCString>& aDnsSuffixList); + nsresult GetResolvers(nsTArray<NetAddr>& aResolvers); + + private: + void EnqueueGenMsg(uint16_t aMsgType, uint8_t aFamily); + void EnqueueRtMsg(uint8_t aFamily, void* aAddress); + void RemovePendingMsg(); + + mozilla::Mutex mMutex MOZ_UNANNOTATED{"NetlinkService::mMutex"}; + + void OnNetlinkMessage(int aNetlinkSocket); + void OnLinkMessage(struct nlmsghdr* aNlh); + void OnAddrMessage(struct nlmsghdr* aNlh); + void OnRouteMessage(struct nlmsghdr* aNlh); + void OnNeighborMessage(struct nlmsghdr* aNlh); + void OnRouteCheckResult(struct nlmsghdr* aNlh); + + void UpdateLinkStatus(); + + void TriggerNetworkIDCalculation(); + int GetPollWait(); + void GetGWNeighboursForFamily(uint8_t aFamily, + nsTArray<NetlinkNeighbor*>& aGwNeighbors); + bool CalculateIDForFamily(uint8_t aFamily, mozilla::SHA1Sum* aSHA1); + void CalculateNetworkID(); + void ExtractDNSProperties(); + + nsCOMPtr<nsIThread> mThread; + + bool mInitialScanFinished{false}; + + // A pipe to signal shutdown with. + int mShutdownPipe[2]{-1, -1}; + + // IP addresses that are used to check the route for public traffic. + struct in_addr mRouteCheckIPv4 {}; + struct in6_addr mRouteCheckIPv6 {}; + + pid_t mPid; + uint32_t mMsgId{0}; + + bool mLinkUp{true}; + + // Flag indicating that network ID could change and should be recalculated. + // Calculation is postponed until we receive responses to all enqueued + // messages. + bool mRecalculateNetworkId{false}; + + // Flag indicating that network change event needs to be sent even if + // network ID hasn't changed. + bool mSendNetworkChangeEvent{false}; + + // Time stamp of setting mRecalculateNetworkId to true + mozilla::TimeStamp mTriggerTime; + + nsCString mNetworkId; + nsTArray<nsCString> mDNSSuffixList; + nsTArray<NetAddr> mDNSResolvers; + + class LinkInfo { + public: + explicit LinkInfo(UniquePtr<NetlinkLink>&& aLink); + virtual ~LinkInfo(); + + // Updates mIsUp according to current mLink and mAddresses. Returns true if + // the value has changed. + bool UpdateStatus(); + + // NetlinkLink structure for this link + UniquePtr<NetlinkLink> mLink; + + // All IPv4/IPv6 addresses on this link + nsTArray<UniquePtr<NetlinkAddress>> mAddresses; + + // All neighbors on this link, key is an address + nsClassHashtable<nsCStringHashKey, NetlinkNeighbor> mNeighbors; + + // Default IPv4/IPv6 routes + nsTArray<UniquePtr<NetlinkRoute>> mDefaultRoutes; + + // Link is up when it's running, it's not a loopback and there is + // a non-local address associated with it. + bool mIsUp; + }; + + bool CalculateIDForEthernetLink(uint8_t aFamily, + NetlinkRoute* aRouteCheckResult, + uint32_t aRouteCheckIfIdx, + LinkInfo* aRouteCheckLinkInfo, + mozilla::SHA1Sum* aSHA1); + bool CalculateIDForNonEthernetLink(uint8_t aFamily, + NetlinkRoute* aRouteCheckResult, + nsTArray<nsCString>& aLinkNamesToHash, + uint32_t aRouteCheckIfIdx, + LinkInfo* aRouteCheckLinkInfo, + mozilla::SHA1Sum* aSHA1); + + nsClassHashtable<nsUint32HashKey, LinkInfo> mLinks; + + // Route for mRouteCheckIPv4 address + UniquePtr<NetlinkRoute> mIPv4RouteCheckResult; + // Route for mRouteCheckIPv6 address + UniquePtr<NetlinkRoute> mIPv6RouteCheckResult; + + nsTArray<UniquePtr<NetlinkMsg>> mOutgoingMessages; + + RefPtr<NetlinkServiceListener> mListener; +}; + +} // namespace net +} // namespace mozilla + +#endif /* NETLINKSERVICE_H_ */ |