1 /*
2  * Copyright (C) 2024-2024 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 "probe_thread.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 
NetProbeThread(const std::shared_ptr<ProbeThread> & probeThread)44 static void NetProbeThread(const std::shared_ptr<ProbeThread> &probeThread)
45 {
46     if (probeThread == nullptr) {
47         NETMGR_LOG_E("probeThread is nullptr");
48         return;
49     }
50     ProbeType type = probeThread->GetProbeType();
51     probeThread->SendHttpProbe(type);
52 }
53 
ProbeThread(uint32_t netId,NetBearType bearType,const NetLinkInfo & netLinkInfo,std::shared_ptr<TinyCountDownLatch> latch,std::shared_ptr<TinyCountDownLatch> latchAll,ProbeType probeType,std::string httpUrl,std::string httpsUrl)54 ProbeThread::ProbeThread(uint32_t netId, NetBearType bearType, const NetLinkInfo &netLinkInfo,
55     std::shared_ptr<TinyCountDownLatch> latch, std::shared_ptr<TinyCountDownLatch> latchAll,
56     ProbeType probeType, std::string httpUrl, std::string httpsUrl)
57     : netId_(netId), probeType_(probeType), latch_(latch), latchAll_(latchAll), httpProbeUrl_(httpUrl),
58     httpsProbeUrl_(httpsUrl)
59 {
60     httpProbe_ = std::make_unique<NetHttpProbe>(netId, bearType, netLinkInfo, probeType);
61 }
62 
~ProbeThread()63 ProbeThread::~ProbeThread()
64 {
65     if (thread_.joinable()) {
66         thread_.join();
67     }
68 }
69 
Start()70 void ProbeThread::Start()
71 {
72     NETMGR_LOG_D("Start net[%{public}d] monitor in", netId_);
73     isDetecting_ = true;
74     std::shared_ptr<ProbeThread> probeThead = shared_from_this();
75     thread_ = std::thread([probeThead] { return NetProbeThread(probeThead);});
76     std::string threadName = "netDetectThread";
77     pthread_setname_np(thread_.native_handle(), threadName.c_str());
78     thread_.detach();
79 }
80 
SendHttpProbe(ProbeType probeType)81 void ProbeThread::SendHttpProbe(ProbeType probeType)
82 {
83     if (httpProbeUrl_.empty() || httpsProbeUrl_.empty()) {
84         NETMGR_LOG_E("Net:[%{public}d] httpProbeUrl is empty", netId_);
85         isDetecting_ = false;
86         latch_->CountDown();
87         latchAll_->CountDown();
88         return;
89     }
90 
91     if (httpProbe_ == nullptr) {
92         NETMGR_LOG_E("Net:[%{public}d] httpProbe_ is nullptr", netId_);
93         isDetecting_ = false;
94         latch_->CountDown();
95         latchAll_->CountDown();
96         return;
97     }
98 
99     if (httpProbe_->SendProbe(probeType, httpProbeUrl_, httpsProbeUrl_) != NETMANAGER_SUCCESS) {
100         NETMGR_LOG_E("Net:[%{public}d] send probe failed.", netId_);
101         isDetecting_ = false;
102         latch_->CountDown();
103         latchAll_->CountDown();
104         return;
105     }
106 
107     if (IsConclusiveResult()) {
108         isDetecting_ = false;
109         while (latch_->GetCount() > 0) {
110             latch_->CountDown();
111         }
112         while (latchAll_->GetCount() > 0) {
113             latchAll_->CountDown();
114         }
115     }
116     isDetecting_ = false;
117     if (latch_->GetCount() > 0) {
118         latch_->CountDown();
119     }
120     if (latchAll_->GetCount() > 0) {
121         latchAll_->CountDown();
122     }
123 }
124 
IsConclusiveResult()125 bool ProbeThread::IsConclusiveResult()
126 {
127     if ((probeType_ == ProbeType::PROBE_HTTP || probeType_ == ProbeType::PROBE_HTTP_FALLBACK) &&
128         httpProbe_->GetHttpProbeResult().IsNeedPortal()) {
129         NETMGR_LOG_I("http url detection result: portal");
130         return true;
131     }
132     if ((probeType_ == ProbeType::PROBE_HTTPS || probeType_ == ProbeType::PROBE_HTTPS_FALLBACK) &&
133         httpProbe_->GetHttpsProbeResult().IsSuccessful()) {
134         NETMGR_LOG_I("https url detection result: success");
135         return true;
136     }
137     return false;
138 }
139 
UpdateGlobalHttpProxy(const HttpProxy & httpProxy)140 void ProbeThread::UpdateGlobalHttpProxy(const HttpProxy &httpProxy)
141 {
142     if (httpProbe_) {
143         httpProbe_->UpdateGlobalHttpProxy(httpProxy);
144     }
145 }
146 
ProbeWithoutGlobalHttpProxy()147 void ProbeThread::ProbeWithoutGlobalHttpProxy()
148 {
149     httpProbe_->ProbeWithoutGlobalHttpProxy();
150 }
151 
GetHttpProbeResult()152 NetHttpProbeResult ProbeThread::GetHttpProbeResult()
153 {
154     return httpProbe_->GetHttpProbeResult();
155 }
156 
GetHttpsProbeResult()157 NetHttpProbeResult ProbeThread::GetHttpsProbeResult()
158 {
159     return httpProbe_->GetHttpsProbeResult();
160 }
161 
IsDetecting()162 bool ProbeThread::IsDetecting()
163 {
164     return isDetecting_.load();
165 }
166 
GetProbeType()167 ProbeType ProbeThread::GetProbeType()
168 {
169     return probeType_;
170 }
171 
172 }
173 }