NetlinkService.h (5235B)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim:set et sw=2 ts=4: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 #ifndef NETLINKSERVICE_H_ 7 #define NETLINKSERVICE_H_ 8 9 #include <netinet/in.h> 10 11 #include "nsIRunnable.h" 12 #include "nsThreadUtils.h" 13 #include "nsCOMPtr.h" 14 #include "mozilla/Mutex.h" 15 #include "mozilla/TimeStamp.h" 16 #include "nsClassHashtable.h" 17 #include "mozilla/SHA1.h" 18 #include "mozilla/UniquePtr.h" 19 #include "nsTArray.h" 20 #include "mozilla/net/DNS.h" 21 22 namespace mozilla { 23 namespace net { 24 25 class NetlinkAddress; 26 class NetlinkNeighbor; 27 class NetlinkLink; 28 class NetlinkRoute; 29 class NetlinkMsg; 30 31 class NetlinkServiceListener : public nsISupports { 32 public: 33 virtual void OnNetworkChanged() = 0; 34 virtual void OnNetworkIDChanged() = 0; 35 virtual void OnLinkUp() = 0; 36 virtual void OnLinkDown() = 0; 37 virtual void OnLinkStatusKnown() = 0; 38 virtual void OnDnsSuffixListUpdated() = 0; 39 40 protected: 41 virtual ~NetlinkServiceListener() = default; 42 }; 43 44 class NetlinkService : public nsIRunnable { 45 virtual ~NetlinkService(); 46 47 public: 48 NS_DECL_THREADSAFE_ISUPPORTS 49 NS_DECL_NSIRUNNABLE 50 51 NetlinkService(); 52 nsresult Init(NetlinkServiceListener* aListener); 53 nsresult Shutdown(); 54 void GetNetworkID(nsACString& aNetworkID); 55 void GetIsLinkUp(bool* aIsUp); 56 nsresult GetDnsSuffixList(nsTArray<nsCString>& aDnsSuffixList); 57 nsresult GetResolvers(nsTArray<NetAddr>& aResolvers); 58 59 static bool HasNonLocalIPv6Address(); 60 61 private: 62 void EnqueueGenMsg(uint16_t aMsgType, uint8_t aFamily); 63 void EnqueueRtMsg(uint8_t aFamily, void* aAddress); 64 void RemovePendingMsg(); 65 66 mozilla::Mutex mMutex MOZ_UNANNOTATED{"NetlinkService::mMutex"}; 67 68 void OnNetlinkMessage(int aNetlinkSocket); 69 void OnLinkMessage(struct nlmsghdr* aNlh); 70 void OnAddrMessage(struct nlmsghdr* aNlh); 71 void OnRouteMessage(struct nlmsghdr* aNlh); 72 void OnNeighborMessage(struct nlmsghdr* aNlh); 73 void OnRouteCheckResult(struct nlmsghdr* aNlh); 74 75 void UpdateLinkStatus(); 76 77 void TriggerNetworkIDCalculation(); 78 int GetPollWait(); 79 void GetGWNeighboursForFamily(uint8_t aFamily, 80 nsTArray<NetlinkNeighbor*>& aGwNeighbors); 81 bool CalculateIDForFamily(uint8_t aFamily, mozilla::SHA1Sum* aSHA1); 82 void CalculateNetworkID(); 83 void ExtractDNSProperties(); 84 85 nsCOMPtr<nsIThread> mThread; 86 87 bool mInitialScanFinished{false}; 88 89 // A pipe to signal shutdown with. 90 int mShutdownPipe[2]{-1, -1}; 91 92 // IP addresses that are used to check the route for public traffic. 93 struct in_addr mRouteCheckIPv4{}; 94 struct in6_addr mRouteCheckIPv6{}; 95 96 pid_t mPid; 97 uint32_t mMsgId{0}; 98 99 bool mLinkUp{true}; 100 101 // Flag indicating that network ID could change and should be recalculated. 102 // Calculation is postponed until we receive responses to all enqueued 103 // messages. 104 bool mRecalculateNetworkId{false}; 105 106 // Flag indicating that network change event needs to be sent even if 107 // network ID hasn't changed. 108 bool mSendNetworkChangeEvent{false}; 109 110 // Time stamp of setting mRecalculateNetworkId to true 111 mozilla::TimeStamp mTriggerTime; 112 113 nsCString mNetworkId; 114 nsTArray<nsCString> mDNSSuffixList; 115 nsTArray<NetAddr> mDNSResolvers; 116 117 class LinkInfo { 118 public: 119 explicit LinkInfo(UniquePtr<NetlinkLink>&& aLink); 120 virtual ~LinkInfo(); 121 122 // Updates mIsUp according to current mLink and mAddresses. Returns true if 123 // the value has changed. 124 bool UpdateStatus(); 125 126 // NetlinkLink structure for this link 127 UniquePtr<NetlinkLink> mLink; 128 129 // All IPv4/IPv6 addresses on this link 130 nsTArray<UniquePtr<NetlinkAddress>> mAddresses; 131 132 // All neighbors on this link, key is an address 133 nsClassHashtable<nsCStringHashKey, NetlinkNeighbor> mNeighbors; 134 135 // Default IPv4/IPv6 routes 136 nsTArray<UniquePtr<NetlinkRoute>> mDefaultRoutes; 137 138 // Link is up when it's running, it's not a loopback and there is 139 // a non-local address associated with it. 140 bool mIsUp; 141 }; 142 143 bool CalculateIDForEthernetLink(uint8_t aFamily, 144 NetlinkRoute* aRouteCheckResult, 145 uint32_t aRouteCheckIfIdx, 146 LinkInfo* aRouteCheckLinkInfo, 147 mozilla::SHA1Sum* aSHA1); 148 bool CalculateIDForNonEthernetLink(uint8_t aFamily, 149 NetlinkRoute* aRouteCheckResult, 150 nsTArray<nsCString>& aLinkNamesToHash, 151 uint32_t aRouteCheckIfIdx, 152 LinkInfo* aRouteCheckLinkInfo, 153 mozilla::SHA1Sum* aSHA1); 154 155 nsClassHashtable<nsUint32HashKey, LinkInfo> mLinks; 156 157 // Route for mRouteCheckIPv4 address 158 UniquePtr<NetlinkRoute> mIPv4RouteCheckResult; 159 // Route for mRouteCheckIPv6 address 160 UniquePtr<NetlinkRoute> mIPv6RouteCheckResult; 161 162 nsTArray<UniquePtr<NetlinkMsg>> mOutgoingMessages; 163 164 RefPtr<NetlinkServiceListener> mListener; 165 }; 166 167 } // namespace net 168 } // namespace mozilla 169 170 #endif /* NETLINKSERVICE_H_ */