• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-2023 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 <arpa/inet.h>
17 #include <cstring>
18 #include <fcntl.h>
19 #include <fstream>
20 #include <future>
21 #include <list>
22 #include <memory>
23 #include <netdb.h>
24 #include <regex>
25 #include <securec.h>
26 #include <sys/socket.h>
27 #include <thread>
28 #include <pthread.h>
29 #include <unistd.h>
30 
31 #include "net_monitor.h"
32 #include "dns_config_client.h"
33 #include "event_report.h"
34 #include "fwmark_client.h"
35 #include "netmanager_base_common_utils.h"
36 #include "netsys_controller.h"
37 #include "net_http_proxy_tracker.h"
38 #include "net_mgr_log_wrapper.h"
39 #include "net_manager_constants.h"
40 
41 namespace OHOS {
42 namespace NetManagerStandard {
43 namespace {
44 constexpr int32_t INIT_DETECTION_DELAY_MS = 1 * 1000;
45 constexpr int32_t MAX_FAILED_DETECTION_DELAY_MS = 10 * 60 * 1000;
46 constexpr int32_t CAPTIVE_PORTAL_DETECTION_DELAY_MS = 30 * 1000;
47 constexpr int32_t DOUBLE = 2;
48 constexpr const char NEW_LINE_STR = '\n';
49 constexpr const char *URL_CFG_FILE = "/system/etc/netdetectionurl.conf";
50 constexpr const char *HTTP_URL_HEADER = "HttpProbeUrl:";
51 constexpr const char *HTTPS_URL_HEADER = "HttpsProbeUrl:";
52 constexpr const char *NET_HTTP_PROBE_URL = "http://connectivitycheck.platform.hicloud.com/generate_204";
53 constexpr const char *NET_HTTPS_PROBE_URL = "https://connectivitycheck.platform.hicloud.com/generate_204";
54 } // namespace
NetDetectThread(const std::shared_ptr<NetMonitor> & netMonitor)55 static void NetDetectThread(const std::shared_ptr<NetMonitor> &netMonitor)
56 {
57     if (netMonitor == nullptr) {
58         NETMGR_LOG_E("netMonitor is nullptr");
59         return;
60     }
61     while (netMonitor->IsDetecting()) {
62         netMonitor->Detection();
63     }
64 }
65 
NetMonitor(uint32_t netId,NetBearType bearType,const NetLinkInfo & netLinkInfo,const std::weak_ptr<INetMonitorCallback> & callback)66 NetMonitor::NetMonitor(uint32_t netId, NetBearType bearType, const NetLinkInfo &netLinkInfo,
67                        const std::weak_ptr<INetMonitorCallback> &callback)
68     : netId_(netId), netMonitorCallback_(callback)
69 {
70     httpProbe_ = std::make_unique<NetHttpProbe>(netId, bearType, netLinkInfo);
71     LoadGlobalHttpProxy();
72 }
73 
Start()74 void NetMonitor::Start()
75 {
76     NETMGR_LOG_I("Start net[%{public}d] monitor in", netId_);
77     if (isDetecting_) {
78         NETMGR_LOG_W("Net[%{public}d] monitor is detecting, no need to start", netId_);
79         return;
80     }
81     isDetecting_ = true;
82     std::shared_ptr<NetMonitor> netMonitor = shared_from_this();
83     std::thread t([netMonitor] { return NetDetectThread(netMonitor); });
84     std::string threadName = "netDetect";
85     pthread_setname_np(t.native_handle(), threadName.c_str());
86     t.detach();
87 }
88 
Stop()89 void NetMonitor::Stop()
90 {
91     NETMGR_LOG_I("Stop net[%{public}d] monitor in", netId_);
92     isDetecting_ = false;
93     detectionCond_.notify_all();
94     NETMGR_LOG_D("Stop net[%{public}d] monitor out", netId_);
95 }
96 
IsDetecting()97 bool NetMonitor::IsDetecting()
98 {
99     return isDetecting_.load();
100 }
101 
Detection()102 void NetMonitor::Detection()
103 {
104     NetHttpProbeResult probeResult = SendHttpProbe(PROBE_HTTP_HTTPS);
105     if (isDetecting_) {
106         NetDetectionStatus result = UNKNOWN_STATE;
107         if (probeResult.IsSuccessful()) {
108             NETMGR_LOG_I("Net[%{public}d] probe success", netId_);
109             isDetecting_ = false;
110             detectionSteps_ = 0;
111             result = VERIFICATION_STATE;
112         } else if (probeResult.IsNeedPortal()) {
113             NETMGR_LOG_W("Net[%{public}d] need portal", netId_);
114             detectionDelay_ = CAPTIVE_PORTAL_DETECTION_DELAY_MS;
115             result = CAPTIVE_PORTAL_STATE;
116         } else {
117             NETMGR_LOG_E("Net[%{public}d] probe failed", netId_);
118             detectionDelay_ *= DOUBLE;
119             if (detectionDelay_ == 0) {
120                 detectionDelay_ = INIT_DETECTION_DELAY_MS;
121             } else if (detectionDelay_ >= MAX_FAILED_DETECTION_DELAY_MS) {
122                 detectionDelay_ = MAX_FAILED_DETECTION_DELAY_MS;
123             }
124             NETMGR_LOG_I("Net probe failed detectionDelay time [%{public}d]", detectionDelay_);
125             detectionSteps_++;
126             result = INVALID_DETECTION_STATE;
127         }
128         auto monitorCallback = netMonitorCallback_.lock();
129         if (monitorCallback) {
130             monitorCallback->OnHandleNetMonitorResult(result, probeResult.GetRedirectUrl());
131         }
132         struct EventInfo eventInfo = {.monitorStatus = static_cast<int32_t>(result)};
133         EventReport::SendMonitorBehaviorEvent(eventInfo);
134         if (isDetecting_) {
135             std::unique_lock<std::mutex> locker(detectionMtx_);
136             detectionCond_.wait_for(locker, std::chrono::milliseconds(detectionDelay_));
137         }
138     }
139 }
140 
SendHttpProbe(ProbeType probeType)141 NetHttpProbeResult NetMonitor::SendHttpProbe(ProbeType probeType)
142 {
143     std::lock_guard<std::mutex> locker(probeMtx_);
144     std::string httpProbeUrl;
145     std::string httpsProbeUrl;
146     GetHttpProbeUrlFromConfig(httpProbeUrl, httpsProbeUrl);
147 
148     if (httpProbe_ == nullptr) {
149         NETMGR_LOG_E("Net:[%{public}d] httpProbe_ is nullptr", netId_);
150         return NetHttpProbeResult();
151     }
152 
153     if (httpProbe_->SendProbe(probeType, httpProbeUrl, httpsProbeUrl) != NETMANAGER_SUCCESS) {
154         NETMGR_LOG_E("Net:[%{public}d] send probe failed.", netId_);
155         return NetHttpProbeResult();
156     }
157 
158     if (httpProbe_->GetHttpProbeResult().IsNeedPortal()) {
159         return httpProbe_->GetHttpProbeResult();
160     }
161 
162 #ifdef NEED_REPORT_PARTIAL_CONNECTION
163     if (httpProbe_->HasProbeType(probeType, ProbeType::PROBE_HTTP) &&
164         httpProbe_->HasProbeType(probeType, ProbeType::PROBE_HTTPS)) {
165         if (httpProbe_->GetHttpProbeResult().IsSuccessful() && httpProbe_->GetHttpsProbeResult().IsFailed) {
166             // return probe result: PARTIAL;
167         }
168     }
169 #endif
170 
171     if (httpProbe_->HasProbeType(probeType, ProbeType::PROBE_HTTPS)) {
172         return httpProbe_->GetHttpsProbeResult();
173     }
174 
175     return httpProbe_->GetHttpProbeResult();
176 }
177 
GetHttpProbeUrlFromConfig(std::string & httpUrl,std::string & httpsUrl)178 void NetMonitor::GetHttpProbeUrlFromConfig(std::string &httpUrl, std::string &httpsUrl)
179 {
180     if (!std::filesystem::exists(URL_CFG_FILE)) {
181         NETMGR_LOG_E("File not exist (%{public}s)", URL_CFG_FILE);
182         return;
183     }
184 
185     std::ifstream file(URL_CFG_FILE);
186     if (!file.is_open()) {
187         NETMGR_LOG_E("Open file failed (%{public}s)", strerror(errno));
188         return;
189     }
190 
191     std::ostringstream oss;
192     oss << file.rdbuf();
193     std::string content = oss.str();
194     auto pos = content.find(HTTP_URL_HEADER);
195     if (pos != std::string::npos) {
196         pos += strlen(HTTP_URL_HEADER);
197         httpUrl = content.substr(pos, content.find(NEW_LINE_STR, pos) - pos);
198     }
199     httpUrl = httpUrl.empty() ? NET_HTTP_PROBE_URL : httpUrl;
200 
201     pos = content.find(HTTPS_URL_HEADER);
202     if (pos != std::string::npos) {
203         pos += strlen(HTTPS_URL_HEADER);
204         httpsUrl = content.substr(pos, content.find(NEW_LINE_STR, pos) - pos);
205     }
206     httpsUrl = httpsUrl.empty() ? NET_HTTPS_PROBE_URL : httpsUrl;
207     NETMGR_LOG_D("Get net detection http url:[%{public}s], https url:[%{public}s]", httpUrl.c_str(), httpsUrl.c_str());
208 }
209 
LoadGlobalHttpProxy()210 void NetMonitor::LoadGlobalHttpProxy()
211 {
212     HttpProxy globalHttpProxy;
213     NetHttpProxyTracker httpProxyTracker;
214     httpProxyTracker.ReadFromSettingsData(globalHttpProxy);
215     UpdateGlobalHttpProxy(globalHttpProxy);
216 }
217 
UpdateGlobalHttpProxy(const HttpProxy & httpProxy)218 void NetMonitor::UpdateGlobalHttpProxy(const HttpProxy &httpProxy)
219 {
220     if (httpProbe_) {
221         httpProbe_->UpdateGlobalHttpProxy(httpProxy);
222     }
223 }
224 } // namespace NetManagerStandard
225 } // namespace OHOS
226