1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "wrapper_distributor.h"
17
18 #include "netmanager_base_common_utils.h"
19 #include "netnative_log_wrapper.h"
20
21 namespace OHOS {
22 namespace nmd {
23 using namespace NetManagerStandard::CommonUtils;
24 namespace {
IsValidMessage(const std::shared_ptr<NetsysEventMessage> & message)25 bool IsValidMessage(const std::shared_ptr<NetsysEventMessage> &message)
26 {
27 return message->GetAction() != NetsysEventMessage::Action::UNKNOWN &&
28 message->GetSubSys() != NetsysEventMessage::SubSys::UNKNOWN;
29 }
30 } // namespace
WrapperDistributor(int32_t socket,const int32_t format,std::mutex & externMutex)31 WrapperDistributor::WrapperDistributor(int32_t socket, const int32_t format, std::mutex& externMutex)
32 : netlinkCallbacksMutex_(externMutex)
33 {
34 NETNATIVE_LOG_D("WrapperDistributor::WrapperDistributor: Socket: %{public}d, Format: %{public}d", socket, format);
35 receiver_ = std::make_unique<DataReceiver>(socket, format);
36 receiver_->RegisterCallback(
37 [this](const std::shared_ptr<NetsysEventMessage> message) { HandleDecodeSuccess(message); });
38 }
39
Start()40 int32_t WrapperDistributor::Start()
41 {
42 return receiver_->Start();
43 }
44
Stop()45 int32_t WrapperDistributor::Stop()
46 {
47 return receiver_->Stop();
48 }
49
RegisterNetlinkCallbacks(std::shared_ptr<std::vector<sptr<NetsysNative::INotifyCallback>>> netlinkCallbacks)50 int32_t WrapperDistributor::RegisterNetlinkCallbacks(
51 std::shared_ptr<std::vector<sptr<NetsysNative::INotifyCallback>>> netlinkCallbacks)
52 {
53 std::lock_guard<std::mutex> lock(netlinkCallbacksMutex_);
54 if (netlinkCallbacks == nullptr) {
55 NETNATIVE_LOGE("netlinkCallbacks is nullptr");
56 return NetlinkResult::ERR_NULL_PTR;
57 }
58 netlinkCallbacks_ = netlinkCallbacks;
59 return NetlinkResult::OK;
60 }
61
HandleDecodeSuccess(const std::shared_ptr<NetsysEventMessage> & message)62 void WrapperDistributor::HandleDecodeSuccess(const std::shared_ptr<NetsysEventMessage> &message)
63 {
64 if (message == nullptr) {
65 NETNATIVE_LOGE("NetlinkProcessor: OnEvent: message is nullptr");
66 return;
67 }
68 if (netlinkCallbacks_ == nullptr) {
69 NETNATIVE_LOGE("netlinkCallbacks_ is nullptr");
70 return;
71 }
72 if (!IsValidMessage(message)) {
73 return;
74 }
75 HandleStateChanged(message);
76 }
77
HandleStateChanged(const std::shared_ptr<NetsysEventMessage> & message)78 void WrapperDistributor::HandleStateChanged(const std::shared_ptr<NetsysEventMessage> &message)
79 {
80 message->DumpMessage();
81 const NetsysEventMessage::SubSys subSys = message->GetSubSys();
82 switch (subSys) {
83 case NetsysEventMessage::SubSys::NET:
84 HandleSubSysNet(message);
85 break;
86 case NetsysEventMessage::SubSys::QLOG:
87 HandleSubSysQlog(message);
88 break;
89 default:
90 break;
91 }
92 }
93
HandleSubSysNet(const std::shared_ptr<NetsysEventMessage> & message)94 void WrapperDistributor::HandleSubSysNet(const std::shared_ptr<NetsysEventMessage> &message)
95 {
96 NetsysEventMessage::Action action = message->GetAction();
97 const std::string &iface = message->GetMessage(NetsysEventMessage::Type::INTERFACE);
98
99 switch (action) {
100 case NetsysEventMessage::Action::ADD:
101 NotifyInterfaceAdd(iface);
102 break;
103 case NetsysEventMessage::Action::REMOVE:
104 NotifyInterfaceRemove(iface);
105 break;
106 case NetsysEventMessage::Action::CHANGE:
107 NotifyInterfaceChange(iface, true);
108 break;
109 case NetsysEventMessage::Action::LINKUP:
110 NotifyInterfaceLinkStateChange(iface, true);
111 break;
112 case NetsysEventMessage::Action::LINKDOWN:
113 NotifyInterfaceLinkStateChange(iface, false);
114 break;
115 case NetsysEventMessage::Action::ADDRESSUPDATE:
116 case NetsysEventMessage::Action::ADDRESSREMOVED:
117 HandleAddressChange(message);
118 break;
119 case NetsysEventMessage::Action::ROUTEUPDATED:
120 case NetsysEventMessage::Action::ROUTEREMOVED:
121 HandleRouteChange(message);
122 break;
123 default:
124 break;
125 }
126 }
127
HandleAddressChange(const std::shared_ptr<NetsysEventMessage> & message)128 void WrapperDistributor::HandleAddressChange(const std::shared_ptr<NetsysEventMessage> &message)
129 {
130 NetsysEventMessage::Action action = message->GetAction();
131 const std::string &iface = message->GetMessage(NetsysEventMessage::Type::INTERFACE);
132 const std::string &address = message->GetMessage(NetsysEventMessage::Type::ADDRESS);
133 const std::string &flags = message->GetMessage(NetsysEventMessage::Type::FLAGS);
134 const std::string &scope = message->GetMessage(NetsysEventMessage::Type::SCOPE);
135 const bool addrUpdated = (action == NetsysEventMessage::Action::ADDRESSUPDATE);
136
137 if (!iface.empty() && iface[0] && !address.empty() && !flags.empty() && !scope.empty()) {
138 if (addrUpdated) {
139 NotifyInterfaceAddressUpdate(address, iface, ConvertToInt64(flags), ConvertToInt64(scope));
140 } else {
141 NotifyInterfaceAddressRemove(address, iface, ConvertToInt64(flags), ConvertToInt64(scope));
142 }
143 }
144 }
145
HandleRouteChange(const std::shared_ptr<NetsysEventMessage> & message)146 void WrapperDistributor::HandleRouteChange(const std::shared_ptr<NetsysEventMessage> &message)
147 {
148 NetsysEventMessage::Action action = message->GetAction();
149 const std::string &route = message->GetMessage(NetsysEventMessage::Type::ROUTE);
150 const std::string &gateway = message->GetMessage(NetsysEventMessage::Type::GATEWAY);
151 const std::string &iface = message->GetMessage(NetsysEventMessage::Type::INTERFACE);
152 if (!route.empty() && (!gateway.empty() || !iface.empty())) {
153 NotifyRouteChange((action == NetsysEventMessage::Action::ROUTEUPDATED), route, gateway, iface);
154 }
155 }
156
HandleSubSysQlog(const std::shared_ptr<NetsysEventMessage> & message)157 void WrapperDistributor::HandleSubSysQlog(const std::shared_ptr<NetsysEventMessage> &message)
158 {
159 const std::string &alertName = message->GetMessage(NetsysEventMessage::Type::ALERT_NAME);
160 const std::string &iface = message->GetMessage(NetsysEventMessage::Type::INTERFACE);
161 if (iface.empty()) {
162 NETNATIVE_LOGW("No interface name in event message");
163 return;
164 }
165 NotifyQuotaLimitReache(alertName, iface);
166 }
167
NotifyInterfaceAdd(const std::string & ifName)168 void WrapperDistributor::NotifyInterfaceAdd(const std::string &ifName)
169 {
170 NETNATIVE_LOG_D("interface added: %{public}s", ifName.c_str());
171 std::lock_guard<std::mutex> lock(netlinkCallbacksMutex_);
172 if (netlinkCallbacks_ == nullptr) {
173 NETNATIVE_LOGE("netlinkCallbacks_ is nullptr");
174 return;
175 }
176 for (auto &callback : *netlinkCallbacks_) {
177 if (callback != nullptr) {
178 callback->OnInterfaceAdded(ifName);
179 }
180 }
181 }
182
NotifyInterfaceRemove(const std::string & ifName)183 void WrapperDistributor::NotifyInterfaceRemove(const std::string &ifName)
184 {
185 NETNATIVE_LOG_D("interface removed: %{public}s", ifName.c_str());
186 std::lock_guard<std::mutex> lock(netlinkCallbacksMutex_);
187 if (netlinkCallbacks_ == nullptr) {
188 NETNATIVE_LOGE("netlinkCallbacks_ is nullptr");
189 return;
190 }
191 for (auto &callback : *netlinkCallbacks_) {
192 if (callback != nullptr) {
193 callback->OnInterfaceRemoved(ifName);
194 }
195 }
196 }
197
NotifyInterfaceChange(const std::string & ifName,bool up)198 void WrapperDistributor::NotifyInterfaceChange(const std::string &ifName, bool up)
199 {
200 NETNATIVE_LOG_D("interface Change: %{public}s, %{public}d", ifName.c_str(), up);
201 std::lock_guard<std::mutex> lock(netlinkCallbacksMutex_);
202 if (netlinkCallbacks_ == nullptr) {
203 NETNATIVE_LOGE("netlinkCallbacks_ is nullptr");
204 return;
205 }
206 for (auto &callback : *netlinkCallbacks_) {
207 if (callback != nullptr) {
208 callback->OnInterfaceChanged(ifName, up);
209 }
210 }
211 }
212
NotifyInterfaceLinkStateChange(const std::string & ifName,bool up)213 void WrapperDistributor::NotifyInterfaceLinkStateChange(const std::string &ifName, bool up)
214 {
215 NETNATIVE_LOG_D("interface link state Change: %{public}s, %{public}d", ifName.c_str(), up);
216 std::lock_guard<std::mutex> lock(netlinkCallbacksMutex_);
217 if (netlinkCallbacks_ == nullptr) {
218 NETNATIVE_LOGE("netlinkCallbacks_ is nullptr");
219 return;
220 }
221 for (auto &callback : *netlinkCallbacks_) {
222 if (callback != nullptr) {
223 callback->OnInterfaceLinkStateChanged(ifName, up);
224 }
225 }
226 }
227
NotifyQuotaLimitReache(const std::string & labelName,const std::string & ifName)228 void WrapperDistributor::NotifyQuotaLimitReache(const std::string &labelName, const std::string &ifName)
229 {
230 NETNATIVE_LOG_D("NotifyQuotaLimitReache: %{public}s, %{public}s", labelName.c_str(), ifName.c_str());
231 std::lock_guard<std::mutex> lock(netlinkCallbacksMutex_);
232 if (netlinkCallbacks_ == nullptr) {
233 NETNATIVE_LOGE("netlinkCallbacks_ is nullptr");
234 return;
235 }
236 for (auto &callback : *netlinkCallbacks_) {
237 if (callback != nullptr) {
238 callback->OnBandwidthReachedLimit(labelName, ifName);
239 }
240 }
241 }
242
NotifyInterfaceAddressUpdate(const std::string & addr,const std::string & ifName,int32_t flags,int32_t scope)243 void WrapperDistributor::NotifyInterfaceAddressUpdate(const std::string &addr, const std::string &ifName,
244 int32_t flags, int32_t scope)
245 {
246 NETNATIVE_LOG_D("OnInterfaceAddressUpdated: %{public}s, %{public}s, %{public}d, %{public}d",
247 ToAnonymousIp(addr).c_str(), ifName.c_str(), flags, scope);
248 std::lock_guard<std::mutex> lock(netlinkCallbacksMutex_);
249 if (netlinkCallbacks_ == nullptr) {
250 NETNATIVE_LOGE("netlinkCallbacks_ is nullptr");
251 return;
252 }
253 for (auto &callback : *netlinkCallbacks_) {
254 if (callback != nullptr) {
255 callback->OnInterfaceAddressUpdated(addr, ifName, flags, scope);
256 }
257 }
258 }
259
NotifyInterfaceAddressRemove(const std::string & addr,const std::string & ifName,int32_t flags,int32_t scope)260 void WrapperDistributor::NotifyInterfaceAddressRemove(const std::string &addr, const std::string &ifName,
261 int32_t flags, int32_t scope)
262 {
263 NETNATIVE_LOG_D("NotifyInterfaceAddressRemove: %{public}s, %{public}s, %{public}d, %{public}d",
264 ToAnonymousIp(addr).c_str(), ifName.c_str(), flags, scope);
265 std::lock_guard<std::mutex> lock(netlinkCallbacksMutex_);
266 if (netlinkCallbacks_ == nullptr) {
267 NETNATIVE_LOGE("netlinkCallbacks_ is nullptr");
268 return;
269 }
270 for (auto &callback : *netlinkCallbacks_) {
271 if (callback != nullptr) {
272 callback->OnInterfaceAddressRemoved(addr, ifName, flags, scope);
273 }
274 }
275 }
276
NotifyRouteChange(bool updated,const std::string & route,const std::string & gateway,const std::string & ifName)277 void WrapperDistributor::NotifyRouteChange(bool updated, const std::string &route, const std::string &gateway,
278 const std::string &ifName)
279 {
280 NETNATIVE_LOG_D("NotifyRouteChange: %{public}s, %{public}s, %{public}s, %{public}s",
281 updated ? "updated" : "removed", ToAnonymousIp(route).c_str(), ToAnonymousIp(gateway).c_str(),
282 ifName.c_str());
283 std::lock_guard<std::mutex> lock(netlinkCallbacksMutex_);
284 if (netlinkCallbacks_ == nullptr) {
285 NETNATIVE_LOGE("netlinkCallbacks_ is nullptr");
286 return;
287 }
288 for (auto &callback : *netlinkCallbacks_) {
289 if (callback != nullptr) {
290 callback->OnRouteChanged(updated, route, gateway, ifName);
291 }
292 }
293 }
294 } // namespace nmd
295 } // namespace OHOS
296