1b1b8bc3fSopenharmony_ci/*
2b1b8bc3fSopenharmony_ci * Copyright (C) 2021-2024 Huawei Device Co., Ltd.
3b1b8bc3fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4b1b8bc3fSopenharmony_ci * you may not use this file except in compliance with the License.
5b1b8bc3fSopenharmony_ci * You may obtain a copy of the License at
6b1b8bc3fSopenharmony_ci *
7b1b8bc3fSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8b1b8bc3fSopenharmony_ci *
9b1b8bc3fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10b1b8bc3fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11b1b8bc3fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12b1b8bc3fSopenharmony_ci * See the License for the specific language governing permissions and
13b1b8bc3fSopenharmony_ci * limitations under the License.
14b1b8bc3fSopenharmony_ci */
15b1b8bc3fSopenharmony_ci
16b1b8bc3fSopenharmony_ci#include <arpa/inet.h>
17b1b8bc3fSopenharmony_ci#include <cstring>
18b1b8bc3fSopenharmony_ci#include <fcntl.h>
19b1b8bc3fSopenharmony_ci#include <fstream>
20b1b8bc3fSopenharmony_ci#include <future>
21b1b8bc3fSopenharmony_ci#include <list>
22b1b8bc3fSopenharmony_ci#include <memory>
23b1b8bc3fSopenharmony_ci#include <netdb.h>
24b1b8bc3fSopenharmony_ci#include <regex>
25b1b8bc3fSopenharmony_ci#include <securec.h>
26b1b8bc3fSopenharmony_ci#include <sys/socket.h>
27b1b8bc3fSopenharmony_ci#include <thread>
28b1b8bc3fSopenharmony_ci#include <pthread.h>
29b1b8bc3fSopenharmony_ci#include <unistd.h>
30b1b8bc3fSopenharmony_ci#include <string>
31b1b8bc3fSopenharmony_ci
32b1b8bc3fSopenharmony_ci#include "net_monitor.h"
33b1b8bc3fSopenharmony_ci#include "dns_config_client.h"
34b1b8bc3fSopenharmony_ci#include "event_report.h"
35b1b8bc3fSopenharmony_ci#include "fwmark_client.h"
36b1b8bc3fSopenharmony_ci#include "netmanager_base_common_utils.h"
37b1b8bc3fSopenharmony_ci#include "netsys_controller.h"
38b1b8bc3fSopenharmony_ci#include "net_http_proxy_tracker.h"
39b1b8bc3fSopenharmony_ci#include "net_mgr_log_wrapper.h"
40b1b8bc3fSopenharmony_ci#include "net_manager_constants.h"
41b1b8bc3fSopenharmony_ci#include "tiny_count_down_latch.h"
42b1b8bc3fSopenharmony_ci
43b1b8bc3fSopenharmony_cinamespace OHOS {
44b1b8bc3fSopenharmony_cinamespace NetManagerStandard {
45b1b8bc3fSopenharmony_cinamespace {
46b1b8bc3fSopenharmony_ciconstexpr int32_t INIT_DETECTION_DELAY_MS = 1 * 1000;
47b1b8bc3fSopenharmony_ciconstexpr int32_t MAX_FAILED_DETECTION_DELAY_MS = 10 * 60 * 1000;
48b1b8bc3fSopenharmony_ciconstexpr int32_t PRIMARY_DETECTION_RESULT_WAIT_MS = 3 * 1000;
49b1b8bc3fSopenharmony_ciconstexpr int32_t ALL_DETECTION_RESULT_WAIT_MS = 10 * 1000;
50b1b8bc3fSopenharmony_ciconstexpr int32_t CAPTIVE_PORTAL_DETECTION_DELAY_MS = 15 * 1000;
51b1b8bc3fSopenharmony_ciconstexpr int32_t DOUBLE = 2;
52b1b8bc3fSopenharmony_ciconstexpr int32_t SIM_PORTAL_CODE = 302;
53b1b8bc3fSopenharmony_ciconstexpr int32_t ONE_URL_DETECT_NUM = 2;
54b1b8bc3fSopenharmony_ciconstexpr int32_t ALL_DETECT_THREAD_NUM = 4;
55b1b8bc3fSopenharmony_ciconstexpr const char NEW_LINE_STR = '\n';
56b1b8bc3fSopenharmony_ciconstexpr const char* URL_CFG_FILE = "/system/etc/netdetectionurl.conf";
57b1b8bc3fSopenharmony_ciconstexpr const char* DETECT_CFG_FILE = "/system/etc/detectionconfig.conf";
58b1b8bc3fSopenharmony_ciconstexpr const char *SETTINGS_DATASHARE_URI =
59b1b8bc3fSopenharmony_ci        "datashare:///com.ohos.settingsdata/entry/settingsdata/SETTINGSDATA?Proxy=true";
60b1b8bc3fSopenharmony_ciconstexpr const char *SETTINGS_DATA_EXT_URI = "datashare:///com.ohos.settingsdata.DataAbility";
61b1b8bc3fSopenharmony_ciconst std::string HTTP_URL_HEADER = "HttpProbeUrl:";
62b1b8bc3fSopenharmony_ciconst std::string HTTPS_URL_HEADER = "HttpsProbeUrl:";
63b1b8bc3fSopenharmony_ciconst std::string FALLBACK_HTTP_URL_HEADER = "FallbackHttpProbeUrl:";
64b1b8bc3fSopenharmony_ciconst std::string FALLBACK_HTTPS_URL_HEADER = "FallbackHttpsProbeUrl:";
65b1b8bc3fSopenharmony_ciconst std::string ADD_RANDOM_CFG_PREFIX = "AddSuffix:";
66b1b8bc3fSopenharmony_ciconst std::string ADD_RANDOM_CFG_VALUE = "true";
67b1b8bc3fSopenharmony_ci} // namespace
68b1b8bc3fSopenharmony_cistatic void NetDetectThread(const std::shared_ptr<NetMonitor> &netMonitor)
69b1b8bc3fSopenharmony_ci{
70b1b8bc3fSopenharmony_ci    if (netMonitor == nullptr) {
71b1b8bc3fSopenharmony_ci        NETMGR_LOG_E("netMonitor is nullptr");
72b1b8bc3fSopenharmony_ci        return;
73b1b8bc3fSopenharmony_ci    }
74b1b8bc3fSopenharmony_ci    while (netMonitor->IsDetecting()) {
75b1b8bc3fSopenharmony_ci        netMonitor->Detection();
76b1b8bc3fSopenharmony_ci    }
77b1b8bc3fSopenharmony_ci}
78b1b8bc3fSopenharmony_ci
79b1b8bc3fSopenharmony_ciNetMonitor::NetMonitor(uint32_t netId, NetBearType bearType, const NetLinkInfo &netLinkInfo,
80b1b8bc3fSopenharmony_ci                       const std::weak_ptr<INetMonitorCallback> &callback)
81b1b8bc3fSopenharmony_ci    : netId_(netId), netLinkInfo_(netLinkInfo), netMonitorCallback_(callback)
82b1b8bc3fSopenharmony_ci{
83b1b8bc3fSopenharmony_ci    netBearType_ = bearType;
84b1b8bc3fSopenharmony_ci    LoadGlobalHttpProxy();
85b1b8bc3fSopenharmony_ci    GetDetectUrlConfig();
86b1b8bc3fSopenharmony_ci    GetHttpProbeUrlFromConfig();
87b1b8bc3fSopenharmony_ci}
88b1b8bc3fSopenharmony_ci
89b1b8bc3fSopenharmony_civoid NetMonitor::Start()
90b1b8bc3fSopenharmony_ci{
91b1b8bc3fSopenharmony_ci    NETMGR_LOG_D("Start net[%{public}d] monitor in", netId_);
92b1b8bc3fSopenharmony_ci    if (isDetecting_) {
93b1b8bc3fSopenharmony_ci        NETMGR_LOG_W("Net[%{public}d] monitor is detecting, no need to start", netId_);
94b1b8bc3fSopenharmony_ci        return;
95b1b8bc3fSopenharmony_ci    }
96b1b8bc3fSopenharmony_ci    isDetecting_ = true;
97b1b8bc3fSopenharmony_ci    std::shared_ptr<NetMonitor> netMonitor = shared_from_this();
98b1b8bc3fSopenharmony_ci    std::thread t([netMonitor] { return NetDetectThread(netMonitor); });
99b1b8bc3fSopenharmony_ci    std::string threadName = "netDetect";
100b1b8bc3fSopenharmony_ci    pthread_setname_np(t.native_handle(), threadName.c_str());
101b1b8bc3fSopenharmony_ci    t.detach();
102b1b8bc3fSopenharmony_ci}
103b1b8bc3fSopenharmony_ci
104b1b8bc3fSopenharmony_civoid NetMonitor::Stop()
105b1b8bc3fSopenharmony_ci{
106b1b8bc3fSopenharmony_ci    NETMGR_LOG_I("Stop net[%{public}d] monitor in", netId_);
107b1b8bc3fSopenharmony_ci    isDetecting_ = false;
108b1b8bc3fSopenharmony_ci    detectionCond_.notify_all();
109b1b8bc3fSopenharmony_ci    NETMGR_LOG_D("Stop net[%{public}d] monitor out", netId_);
110b1b8bc3fSopenharmony_ci}
111b1b8bc3fSopenharmony_ci
112b1b8bc3fSopenharmony_cibool NetMonitor::IsDetecting()
113b1b8bc3fSopenharmony_ci{
114b1b8bc3fSopenharmony_ci    return isDetecting_.load();
115b1b8bc3fSopenharmony_ci}
116b1b8bc3fSopenharmony_ci
117b1b8bc3fSopenharmony_civoid NetMonitor::ProcessDetection(NetHttpProbeResult& probeResult, NetDetectionStatus& result)
118b1b8bc3fSopenharmony_ci{
119b1b8bc3fSopenharmony_ci    if (probeResult.IsSuccessful()) {
120b1b8bc3fSopenharmony_ci        NETMGR_LOG_I("Net[%{public}d] probe success", netId_);
121b1b8bc3fSopenharmony_ci        isDetecting_ = false;
122b1b8bc3fSopenharmony_ci        needDetectionWithoutProxy_ = true;
123b1b8bc3fSopenharmony_ci        result = VERIFICATION_STATE;
124b1b8bc3fSopenharmony_ci    } else if (probeResult.GetCode() == SIM_PORTAL_CODE && netBearType_ == BEARER_CELLULAR) {
125b1b8bc3fSopenharmony_ci        NETMGR_LOG_E("Net[%{public}d] probe failed with 302 response on Cell", netId_);
126b1b8bc3fSopenharmony_ci        detectionDelay_ = MAX_FAILED_DETECTION_DELAY_MS;
127b1b8bc3fSopenharmony_ci        result = CAPTIVE_PORTAL_STATE;
128b1b8bc3fSopenharmony_ci    } else if (probeResult.IsNeedPortal()) {
129b1b8bc3fSopenharmony_ci        NETMGR_LOG_W("Net[%{public}d] need portal", netId_);
130b1b8bc3fSopenharmony_ci        detectionDelay_ = CAPTIVE_PORTAL_DETECTION_DELAY_MS;
131b1b8bc3fSopenharmony_ci        result = CAPTIVE_PORTAL_STATE;
132b1b8bc3fSopenharmony_ci    } else {
133b1b8bc3fSopenharmony_ci        NETMGR_LOG_E("Net[%{public}d] probe failed", netId_);
134b1b8bc3fSopenharmony_ci        detectionDelay_ *= DOUBLE;
135b1b8bc3fSopenharmony_ci        if (detectionDelay_ == 0) {
136b1b8bc3fSopenharmony_ci            detectionDelay_ = INIT_DETECTION_DELAY_MS;
137b1b8bc3fSopenharmony_ci        } else if (detectionDelay_ >= MAX_FAILED_DETECTION_DELAY_MS) {
138b1b8bc3fSopenharmony_ci            detectionDelay_ = MAX_FAILED_DETECTION_DELAY_MS;
139b1b8bc3fSopenharmony_ci        }
140b1b8bc3fSopenharmony_ci        NETMGR_LOG_I("Net probe failed detectionDelay time [%{public}d]", detectionDelay_);
141b1b8bc3fSopenharmony_ci        result = INVALID_DETECTION_STATE;
142b1b8bc3fSopenharmony_ci    }
143b1b8bc3fSopenharmony_ci    auto monitorCallback = netMonitorCallback_.lock();
144b1b8bc3fSopenharmony_ci    if (monitorCallback) {
145b1b8bc3fSopenharmony_ci        monitorCallback->OnHandleNetMonitorResult(result, probeResult.GetRedirectUrl());
146b1b8bc3fSopenharmony_ci    }
147b1b8bc3fSopenharmony_ci    struct EventInfo eventInfo = {.monitorStatus = static_cast<int32_t>(result)};
148b1b8bc3fSopenharmony_ci    EventReport::SendMonitorBehaviorEvent(eventInfo);
149b1b8bc3fSopenharmony_ci    if (isDetecting_) {
150b1b8bc3fSopenharmony_ci        std::unique_lock<std::mutex> locker(detectionMtx_);
151b1b8bc3fSopenharmony_ci        detectionCond_.wait_for(locker, std::chrono::milliseconds(detectionDelay_));
152b1b8bc3fSopenharmony_ci    }
153b1b8bc3fSopenharmony_ci}
154b1b8bc3fSopenharmony_ci
155b1b8bc3fSopenharmony_civoid NetMonitor::Detection()
156b1b8bc3fSopenharmony_ci{
157b1b8bc3fSopenharmony_ci    NetHttpProbeResult probeResult = SendProbe();
158b1b8bc3fSopenharmony_ci    if (isDetecting_) {
159b1b8bc3fSopenharmony_ci        NetDetectionStatus result = UNKNOWN_STATE;
160b1b8bc3fSopenharmony_ci        ProcessDetection(probeResult, result);
161b1b8bc3fSopenharmony_ci    }
162b1b8bc3fSopenharmony_ci}
163b1b8bc3fSopenharmony_ci
164b1b8bc3fSopenharmony_ciNetHttpProbeResult NetMonitor::SendProbe()
165b1b8bc3fSopenharmony_ci{
166b1b8bc3fSopenharmony_ci    NETMGR_LOG_I("start net detection");
167b1b8bc3fSopenharmony_ci    std::lock_guard<std::mutex> monitorLocker(probeMtx_);
168b1b8bc3fSopenharmony_ci    std::shared_ptr<TinyCountDownLatch> latch = std::make_shared<TinyCountDownLatch>(ONE_URL_DETECT_NUM);
169b1b8bc3fSopenharmony_ci    std::shared_ptr<TinyCountDownLatch> latchAll = std::make_shared<TinyCountDownLatch>(ALL_DETECT_THREAD_NUM);
170b1b8bc3fSopenharmony_ci    std::shared_ptr<ProbeThread> primaryHttpThread = std::make_shared<ProbeThread>(
171b1b8bc3fSopenharmony_ci        netId_, netBearType_, netLinkInfo_, latch, latchAll, ProbeType::PROBE_HTTP, httpUrl_, httpsUrl_);
172b1b8bc3fSopenharmony_ci    std::shared_ptr<ProbeThread> primaryHttpsThread = std::make_shared<ProbeThread>(
173b1b8bc3fSopenharmony_ci        netId_, netBearType_, netLinkInfo_, latch, latchAll, ProbeType::PROBE_HTTPS, httpUrl_, httpsUrl_);
174b1b8bc3fSopenharmony_ci    {
175b1b8bc3fSopenharmony_ci        std::lock_guard<std::mutex> proxyLocker(proxyMtx_);
176b1b8bc3fSopenharmony_ci        primaryHttpThread->UpdateGlobalHttpProxy(globalHttpProxy_);
177b1b8bc3fSopenharmony_ci        primaryHttpsThread->UpdateGlobalHttpProxy(globalHttpProxy_);
178b1b8bc3fSopenharmony_ci    }
179b1b8bc3fSopenharmony_ci    primaryHttpThread->Start();
180b1b8bc3fSopenharmony_ci    primaryHttpsThread->Start();
181b1b8bc3fSopenharmony_ci
182b1b8bc3fSopenharmony_ci    latch->Await(std::chrono::milliseconds(PRIMARY_DETECTION_RESULT_WAIT_MS));
183b1b8bc3fSopenharmony_ci    NetHttpProbeResult httpProbeResult = GetThreadDetectResult(primaryHttpThread, ProbeType::PROBE_HTTP);
184b1b8bc3fSopenharmony_ci    NetHttpProbeResult httpsProbeResult = GetThreadDetectResult(primaryHttpsThread, ProbeType::PROBE_HTTPS);
185b1b8bc3fSopenharmony_ci    if (httpProbeResult.IsNeedPortal()) {
186b1b8bc3fSopenharmony_ci        NETMGR_LOG_I("http detect result: portal");
187b1b8bc3fSopenharmony_ci        return httpProbeResult;
188b1b8bc3fSopenharmony_ci    }
189b1b8bc3fSopenharmony_ci    if (httpsProbeResult.IsSuccessful()) {
190b1b8bc3fSopenharmony_ci        NETMGR_LOG_I("https detect result: success");
191b1b8bc3fSopenharmony_ci        return httpsProbeResult;
192b1b8bc3fSopenharmony_ci    }
193b1b8bc3fSopenharmony_ci    NETMGR_LOG_I("backup url detection start");
194b1b8bc3fSopenharmony_ci    std::shared_ptr<ProbeThread> fallbackHttpThread = std::make_shared<ProbeThread>(netId_,
195b1b8bc3fSopenharmony_ci        netBearType_, netLinkInfo_, latch, latchAll, ProbeType::PROBE_HTTP, fallbackHttpUrl_, fallbackHttpsUrl_);
196b1b8bc3fSopenharmony_ci    std::shared_ptr<ProbeThread> fallbackHttpsThread = std::make_shared<ProbeThread>(netId_,
197b1b8bc3fSopenharmony_ci        netBearType_, netLinkInfo_, latch, latchAll, ProbeType::PROBE_HTTPS, fallbackHttpUrl_, fallbackHttpsUrl_);
198b1b8bc3fSopenharmony_ci    fallbackHttpThread->ProbeWithoutGlobalHttpProxy();
199b1b8bc3fSopenharmony_ci    fallbackHttpsThread->ProbeWithoutGlobalHttpProxy();
200b1b8bc3fSopenharmony_ci    fallbackHttpThread->Start();
201b1b8bc3fSopenharmony_ci    fallbackHttpsThread->Start();
202b1b8bc3fSopenharmony_ci    latchAll->Await(std::chrono::milliseconds(ALL_DETECTION_RESULT_WAIT_MS));
203b1b8bc3fSopenharmony_ci    httpProbeResult = GetThreadDetectResult(primaryHttpThread, ProbeType::PROBE_HTTP);
204b1b8bc3fSopenharmony_ci    httpsProbeResult = GetThreadDetectResult(primaryHttpsThread, ProbeType::PROBE_HTTPS);
205b1b8bc3fSopenharmony_ci    NetHttpProbeResult fallbackHttpProbeResult = GetThreadDetectResult(fallbackHttpThread, ProbeType::PROBE_HTTP);
206b1b8bc3fSopenharmony_ci    NetHttpProbeResult fallbackHttpsProbeResult = GetThreadDetectResult(fallbackHttpsThread, ProbeType::PROBE_HTTPS);
207b1b8bc3fSopenharmony_ci    return ProcessThreadDetectResult(httpProbeResult, httpsProbeResult, fallbackHttpProbeResult,
208b1b8bc3fSopenharmony_ci        fallbackHttpsProbeResult);
209b1b8bc3fSopenharmony_ci}
210b1b8bc3fSopenharmony_ci
211b1b8bc3fSopenharmony_ciNetHttpProbeResult NetMonitor::GetThreadDetectResult(std::shared_ptr<ProbeThread>& probeThread, ProbeType probeType)
212b1b8bc3fSopenharmony_ci{
213b1b8bc3fSopenharmony_ci    NetHttpProbeResult result;
214b1b8bc3fSopenharmony_ci    if (!probeThread->IsDetecting()) {
215b1b8bc3fSopenharmony_ci        if (probeType == ProbeType::PROBE_HTTP) {
216b1b8bc3fSopenharmony_ci            return probeThread->GetHttpProbeResult();
217b1b8bc3fSopenharmony_ci        } else {
218b1b8bc3fSopenharmony_ci            return probeThread->GetHttpsProbeResult();
219b1b8bc3fSopenharmony_ci        }
220b1b8bc3fSopenharmony_ci    }
221b1b8bc3fSopenharmony_ci    return result;
222b1b8bc3fSopenharmony_ci}
223b1b8bc3fSopenharmony_ci
224b1b8bc3fSopenharmony_ciNetHttpProbeResult NetMonitor::ProcessThreadDetectResult(NetHttpProbeResult& httpProbeResult,
225b1b8bc3fSopenharmony_ci    NetHttpProbeResult& httpsProbeResult, NetHttpProbeResult& fallbackHttpProbeResult,
226b1b8bc3fSopenharmony_ci    NetHttpProbeResult& fallbackHttpsProbeResult)
227b1b8bc3fSopenharmony_ci{
228b1b8bc3fSopenharmony_ci    if (httpProbeResult.IsNeedPortal()) {
229b1b8bc3fSopenharmony_ci        NETMGR_LOG_I("primary http detect result: portal");
230b1b8bc3fSopenharmony_ci        return httpProbeResult;
231b1b8bc3fSopenharmony_ci    }
232b1b8bc3fSopenharmony_ci    if (fallbackHttpProbeResult.IsNeedPortal()) {
233b1b8bc3fSopenharmony_ci        NETMGR_LOG_I("fallback http detect result: portal");
234b1b8bc3fSopenharmony_ci        return fallbackHttpProbeResult;
235b1b8bc3fSopenharmony_ci    }
236b1b8bc3fSopenharmony_ci    if (httpsProbeResult.IsSuccessful()) {
237b1b8bc3fSopenharmony_ci        NETMGR_LOG_I("primary https detect result: success");
238b1b8bc3fSopenharmony_ci        return httpsProbeResult;
239b1b8bc3fSopenharmony_ci    }
240b1b8bc3fSopenharmony_ci    if (fallbackHttpsProbeResult.IsSuccessful()) {
241b1b8bc3fSopenharmony_ci        NETMGR_LOG_I("fallback https detect result: success");
242b1b8bc3fSopenharmony_ci        return fallbackHttpsProbeResult;
243b1b8bc3fSopenharmony_ci    }
244b1b8bc3fSopenharmony_ci    if (httpProbeResult.IsSuccessful() && fallbackHttpProbeResult.IsSuccessful()) {
245b1b8bc3fSopenharmony_ci        NETMGR_LOG_I("both primary http and fallback http detect result success");
246b1b8bc3fSopenharmony_ci        return httpProbeResult;
247b1b8bc3fSopenharmony_ci    }
248b1b8bc3fSopenharmony_ci    return httpsProbeResult;
249b1b8bc3fSopenharmony_ci}
250b1b8bc3fSopenharmony_ci
251b1b8bc3fSopenharmony_civoid NetMonitor::LoadGlobalHttpProxy()
252b1b8bc3fSopenharmony_ci{
253b1b8bc3fSopenharmony_ci    if (!CheckIfSettingsDataReady()) {
254b1b8bc3fSopenharmony_ci        NETMGR_LOG_E("data_share is not ready");
255b1b8bc3fSopenharmony_ci        return;
256b1b8bc3fSopenharmony_ci    }
257b1b8bc3fSopenharmony_ci    NetHttpProxyTracker httpProxyTracker;
258b1b8bc3fSopenharmony_ci    httpProxyTracker.ReadFromSettingsData(globalHttpProxy_);
259b1b8bc3fSopenharmony_ci}
260b1b8bc3fSopenharmony_ci
261b1b8bc3fSopenharmony_civoid NetMonitor::UpdateGlobalHttpProxy(const HttpProxy &httpProxy)
262b1b8bc3fSopenharmony_ci{
263b1b8bc3fSopenharmony_ci    std::unique_lock<std::mutex> proxyLocker(proxyMtx_);
264b1b8bc3fSopenharmony_ci    globalHttpProxy_ = httpProxy;
265b1b8bc3fSopenharmony_ci}
266b1b8bc3fSopenharmony_ci
267b1b8bc3fSopenharmony_civoid NetMonitor::GetHttpProbeUrlFromConfig()
268b1b8bc3fSopenharmony_ci{
269b1b8bc3fSopenharmony_ci    if (!std::filesystem::exists(URL_CFG_FILE)) {
270b1b8bc3fSopenharmony_ci        NETMGR_LOG_E("File not exist (%{public}s)", URL_CFG_FILE);
271b1b8bc3fSopenharmony_ci        return;
272b1b8bc3fSopenharmony_ci    }
273b1b8bc3fSopenharmony_ci
274b1b8bc3fSopenharmony_ci    std::ifstream file(URL_CFG_FILE);
275b1b8bc3fSopenharmony_ci    if (!file.is_open()) {
276b1b8bc3fSopenharmony_ci        NETMGR_LOG_E("Open file failed (%{public}s)", strerror(errno));
277b1b8bc3fSopenharmony_ci        return;
278b1b8bc3fSopenharmony_ci    }
279b1b8bc3fSopenharmony_ci
280b1b8bc3fSopenharmony_ci    std::ostringstream oss;
281b1b8bc3fSopenharmony_ci    oss << file.rdbuf();
282b1b8bc3fSopenharmony_ci    std::string content = oss.str();
283b1b8bc3fSopenharmony_ci    auto pos = content.find(HTTP_URL_HEADER);
284b1b8bc3fSopenharmony_ci    if (pos != std::string::npos) {
285b1b8bc3fSopenharmony_ci        pos += HTTP_URL_HEADER.length();
286b1b8bc3fSopenharmony_ci        httpUrl_ = content.substr(pos, content.find(NEW_LINE_STR, pos) - pos);
287b1b8bc3fSopenharmony_ci        if (isNeedSuffix_) {
288b1b8bc3fSopenharmony_ci            uint64_t ranNum = CommonUtils::GenRandomNumber();
289b1b8bc3fSopenharmony_ci            httpUrl_ = httpUrl_ + std::string("_") + std::to_string(ranNum);
290b1b8bc3fSopenharmony_ci        }
291b1b8bc3fSopenharmony_ci    }
292b1b8bc3fSopenharmony_ci
293b1b8bc3fSopenharmony_ci    pos = content.find(HTTPS_URL_HEADER);
294b1b8bc3fSopenharmony_ci    if (pos != std::string::npos) {
295b1b8bc3fSopenharmony_ci        pos += HTTPS_URL_HEADER.length();
296b1b8bc3fSopenharmony_ci        httpsUrl_ = content.substr(pos, content.find(NEW_LINE_STR, pos) - pos);
297b1b8bc3fSopenharmony_ci    }
298b1b8bc3fSopenharmony_ci
299b1b8bc3fSopenharmony_ci    pos = content.find(FALLBACK_HTTP_URL_HEADER);
300b1b8bc3fSopenharmony_ci    if (pos != std::string::npos) {
301b1b8bc3fSopenharmony_ci        pos += FALLBACK_HTTP_URL_HEADER.length();
302b1b8bc3fSopenharmony_ci        fallbackHttpUrl_ = content.substr(pos, content.find(NEW_LINE_STR, pos) - pos);
303b1b8bc3fSopenharmony_ci    }
304b1b8bc3fSopenharmony_ci
305b1b8bc3fSopenharmony_ci    pos = content.find(FALLBACK_HTTPS_URL_HEADER);
306b1b8bc3fSopenharmony_ci    if (pos != std::string::npos) {
307b1b8bc3fSopenharmony_ci        pos += FALLBACK_HTTPS_URL_HEADER.length();
308b1b8bc3fSopenharmony_ci        fallbackHttpsUrl_ = content.substr(pos, content.find(NEW_LINE_STR, pos) - pos);
309b1b8bc3fSopenharmony_ci    }
310b1b8bc3fSopenharmony_ci    NETMGR_LOG_D("Get net detection http url:[%{public}s], https url:[%{public}s], fallback http url:[%{public}s],"
311b1b8bc3fSopenharmony_ci        " fallback https url:[%{public}s]", httpUrl_.c_str(), httpsUrl_.c_str(), fallbackHttpUrl_.c_str(),
312b1b8bc3fSopenharmony_ci        fallbackHttpsUrl_.c_str());
313b1b8bc3fSopenharmony_ci}
314b1b8bc3fSopenharmony_ci
315b1b8bc3fSopenharmony_civoid NetMonitor::GetDetectUrlConfig()
316b1b8bc3fSopenharmony_ci{
317b1b8bc3fSopenharmony_ci    if (!std::filesystem::exists(DETECT_CFG_FILE)) {
318b1b8bc3fSopenharmony_ci        NETMGR_LOG_E("File not exist (%{public}s)", DETECT_CFG_FILE);
319b1b8bc3fSopenharmony_ci        return;
320b1b8bc3fSopenharmony_ci    }
321b1b8bc3fSopenharmony_ci
322b1b8bc3fSopenharmony_ci    std::ifstream file(DETECT_CFG_FILE);
323b1b8bc3fSopenharmony_ci    if (!file.is_open()) {
324b1b8bc3fSopenharmony_ci        NETMGR_LOG_E("Open file failed (%{public}s)", strerror(errno));
325b1b8bc3fSopenharmony_ci        return;
326b1b8bc3fSopenharmony_ci    }
327b1b8bc3fSopenharmony_ci    std::ostringstream oss;
328b1b8bc3fSopenharmony_ci    oss << file.rdbuf();
329b1b8bc3fSopenharmony_ci    std::string content = oss.str();
330b1b8bc3fSopenharmony_ci    auto pos = content.find(ADD_RANDOM_CFG_PREFIX);
331b1b8bc3fSopenharmony_ci    if (pos != std::string::npos) {
332b1b8bc3fSopenharmony_ci        pos += ADD_RANDOM_CFG_PREFIX.length();
333b1b8bc3fSopenharmony_ci        std::string value = content.substr(pos, content.find(NEW_LINE_STR, pos) - pos);
334b1b8bc3fSopenharmony_ci        value = CommonUtils::Trim(value);
335b1b8bc3fSopenharmony_ci        isNeedSuffix_ = value.compare(ADD_RANDOM_CFG_VALUE) == 0;
336b1b8bc3fSopenharmony_ci    }
337b1b8bc3fSopenharmony_ci    NETMGR_LOG_I("is need add suffix (%{public}d)", isNeedSuffix_);
338b1b8bc3fSopenharmony_ci}
339b1b8bc3fSopenharmony_ci
340b1b8bc3fSopenharmony_cibool NetMonitor::CheckIfSettingsDataReady()
341b1b8bc3fSopenharmony_ci{
342b1b8bc3fSopenharmony_ci    if (isDataShareReady_) {
343b1b8bc3fSopenharmony_ci        return true;
344b1b8bc3fSopenharmony_ci    }
345b1b8bc3fSopenharmony_ci    sptr<ISystemAbilityManager> saManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
346b1b8bc3fSopenharmony_ci    if (saManager == nullptr) {
347b1b8bc3fSopenharmony_ci        NETMGR_LOG_E("GetSystemAbilityManager failed.");
348b1b8bc3fSopenharmony_ci        return false;
349b1b8bc3fSopenharmony_ci    }
350b1b8bc3fSopenharmony_ci    sptr<IRemoteObject> dataShareSa = saManager->GetSystemAbility(DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID);
351b1b8bc3fSopenharmony_ci    if (dataShareSa == nullptr) {
352b1b8bc3fSopenharmony_ci        NETMGR_LOG_E("Get dataShare SA Failed.");
353b1b8bc3fSopenharmony_ci        return false;
354b1b8bc3fSopenharmony_ci    }
355b1b8bc3fSopenharmony_ci    sptr<IRemoteObject> remoteObj = saManager->GetSystemAbility(COMM_NET_CONN_MANAGER_SYS_ABILITY_ID);
356b1b8bc3fSopenharmony_ci    if (remoteObj == nullptr) {
357b1b8bc3fSopenharmony_ci        NETMGR_LOG_E("NetDataShareHelperUtils GetSystemAbility Service Failed.");
358b1b8bc3fSopenharmony_ci        return false;
359b1b8bc3fSopenharmony_ci    }
360b1b8bc3fSopenharmony_ci    std::pair<int, std::shared_ptr<DataShare::DataShareHelper>> ret =
361b1b8bc3fSopenharmony_ci            DataShare::DataShareHelper::Create(remoteObj, SETTINGS_DATASHARE_URI, SETTINGS_DATA_EXT_URI);
362b1b8bc3fSopenharmony_ci    NETMGR_LOG_I("create data_share helper, ret=%{public}d", ret.first);
363b1b8bc3fSopenharmony_ci    if (ret.first == DataShare::E_OK) {
364b1b8bc3fSopenharmony_ci        NETMGR_LOG_I("create data_share helper success");
365b1b8bc3fSopenharmony_ci        auto helper = ret.second;
366b1b8bc3fSopenharmony_ci        if (helper != nullptr) {
367b1b8bc3fSopenharmony_ci            bool releaseRet = helper->Release();
368b1b8bc3fSopenharmony_ci            NETMGR_LOG_I("release data_share helper, releaseRet=%{public}d", releaseRet);
369b1b8bc3fSopenharmony_ci        }
370b1b8bc3fSopenharmony_ci        isDataShareReady_ = true;
371b1b8bc3fSopenharmony_ci        return true;
372b1b8bc3fSopenharmony_ci    } else if (ret.first == DataShare::E_DATA_SHARE_NOT_READY) {
373b1b8bc3fSopenharmony_ci        NETMGR_LOG_E("create data_share helper failed");
374b1b8bc3fSopenharmony_ci        isDataShareReady_ = false;
375b1b8bc3fSopenharmony_ci        return false;
376b1b8bc3fSopenharmony_ci    }
377b1b8bc3fSopenharmony_ci    NETMGR_LOG_E("data_share unknown.");
378b1b8bc3fSopenharmony_ci    return true;
379b1b8bc3fSopenharmony_ci}
380b1b8bc3fSopenharmony_ci} // namespace NetManagerStandard
381b1b8bc3fSopenharmony_ci} // namespace OHOS
382