• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-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 <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 <unistd.h>
29 #include "dns_config_client.h"
30 
31 #include "event_report.h"
32 #include "fwmark_client.h"
33 #include "netmanager_base_common_utils.h"
34 #include "netsys_controller.h"
35 #include "net_mgr_log_wrapper.h"
36 #include "net_monitor.h"
37 
38 namespace OHOS {
39 namespace NetManagerStandard {
40 static constexpr int32_t INIT_DETECTION_DELAY_MS = 8 * 1000;
41 static constexpr int32_t MAX_FAILED_DETECTION_DELAY_MS = 5 * 60 * 1000;
42 static constexpr int32_t SUCCESSED_DETECTION_DELAY_MS = 30 * 1000;
43 static constexpr int32_t CAPTIVE_PORTAL_DETECTION_DELAY_MS = 60 * 1000;
44 static constexpr int32_t DOUBLE = 2;
45 static constexpr int32_t DOMAINIPADDR = 128;
46 static constexpr int32_t PORTAL_CONTENT_LENGTH_MIN = 4;
47 static constexpr int32_t NET_CONTENT_LENGTH = 6;
48 static constexpr uint16_t DEFAULT_PORT = 80;
49 static constexpr int32_t MAX_RECIVE_SIZE = 2048;
50 static constexpr int32_t DOMAIN_POSITION = 3;
51 static constexpr int32_t URLPATH_POSITION = 4;
52 static constexpr int32_t SOCKET_TIMEOUT = 2;
53 static constexpr int32_t MAX_SEND_RETRY = 4;
54 static constexpr uint8_t SOCKET_NOT_READY = 0;
55 static constexpr uint8_t SOCKET_READY = 1;
56 constexpr const char *PORTAL_URL_REDIRECT_FIRST_CASE = "Location: ";
57 constexpr const char *PORTAL_URL_REDIRECT_SECOND_CASE = "http";
58 constexpr const char *CONTENT_STR = "Content-Length:";
59 constexpr const char *PORTAL_END_STR = ".com";
60 constexpr const char SPACE_STR = ' ';
61 constexpr const char NEW_LINE_STR = '\n';
62 constexpr const char *URL_CFG_FILE = "/system/etc/netdetectionurl.conf";
63 constexpr const char *DEF_NETDETECT_URL = "http://connectivitycheck.platform.hicloud.com/generate_204";
64 
NetDetectThread(const std::shared_ptr<NetMonitor> & netMonitor)65 static void NetDetectThread(const std::shared_ptr<NetMonitor> &netMonitor)
66 {
67     if (netMonitor == nullptr) {
68         NETMGR_LOG_E("netMonitor is nullptr");
69         return;
70     }
71     while (netMonitor->IsDetecting()) {
72         netMonitor->Detection();
73     }
74 }
75 
NetMonitor(uint32_t netId,const std::weak_ptr<INetMonitorCallback> & callback)76 NetMonitor::NetMonitor(uint32_t netId, const std::weak_ptr<INetMonitorCallback> &callback)
77     : netId_(netId), netMonitorCallback_(callback)
78 {
79 }
80 
Start()81 void NetMonitor::Start()
82 {
83     NETMGR_LOG_I("Start net[%{public}d] monitor in", netId_);
84     if (isDetecting_) {
85         NETMGR_LOG_W("Net[%{public}d] monitor is detecting, no need to start", netId_);
86         return;
87     }
88     isDetecting_ = true;
89     std::shared_ptr<NetMonitor> netMonitor = shared_from_this();
90     std::thread([netMonitor] { return NetDetectThread(netMonitor); }).detach();
91 }
92 
Stop()93 void NetMonitor::Stop()
94 {
95     NETMGR_LOG_I("Stop net[%{public}d] monitor in", netId_);
96     isDetecting_ = false;
97     detectionCond_.notify_all();
98     NETMGR_LOG_I("Stop net[%{public}d] monitor out", netId_);
99 }
100 
IsDetecting()101 bool NetMonitor::IsDetecting()
102 {
103     return isDetecting_.load();
104 }
105 
Detection()106 void NetMonitor::Detection()
107 {
108     NetDetectionStatus result = SendParallelHttpProbes();
109     struct EventInfo eventInfo = {.monitorStatus = static_cast<int32_t>(result)};
110     EventReport::SendMonitorBehaviorEvent(eventInfo);
111     if (isDetecting_) {
112         if (result == CAPTIVE_PORTAL_STATE) {
113             NETMGR_LOG_I("currentNetMonitor[%{public}d] need portal", netId_);
114             detectionDelay_ = CAPTIVE_PORTAL_DETECTION_DELAY_MS;
115         } else if (result == VERIFICATION_STATE) {
116             NETMGR_LOG_I("currentNetMonitor[%{public}d] evaluation success", netId_);
117             detectionDelay_ = SUCCESSED_DETECTION_DELAY_MS;
118             detectionSteps_ = 0;
119         } else {
120             NETMGR_LOG_I("currentNetMonitor[%{public}d] evaluation failed", netId_);
121             detectionDelay_ = static_cast<uint32_t>(INIT_DETECTION_DELAY_MS * DOUBLE * detectionSteps_);
122             if (detectionDelay_ == 0) {
123                 detectionDelay_ = INIT_DETECTION_DELAY_MS;
124             } else if (detectionDelay_ >= MAX_FAILED_DETECTION_DELAY_MS) {
125                 detectionDelay_ = MAX_FAILED_DETECTION_DELAY_MS;
126             }
127             detectionSteps_++;
128         }
129         auto monitorCallback = netMonitorCallback_.lock();
130         if (monitorCallback) {
131             monitorCallback->OnHandleNetMonitorResult(result, portalUrlRedirect_);
132         }
133         if (isDetecting_) {
134             std::unique_lock<std::mutex> locker(detectionMtx_);
135             detectionCond_.wait_for(locker, std::chrono::milliseconds(detectionDelay_));
136         }
137     }
138 }
139 
SendParallelHttpProbes()140 NetDetectionStatus NetMonitor::SendParallelHttpProbes()
141 {
142     std::string url;
143     if (GetDefaultNetDetectionUrlFromCfg(url) != 0) {
144         NETMGR_LOG_I("GetDefaultNetDetectionUrlFromCfg failed, use default url");
145         url = DEF_NETDETECT_URL;
146     }
147     std::string domain;
148     std::string urlPath;
149     if (ParseUrl(url, domain, urlPath)) {
150         NETMGR_LOG_E("Parse net[%{public}d] url:%{public}s error", netId_, url.c_str());
151         return INVALID_DETECTION_STATE;
152     }
153     return SendHttpProbe(domain, urlPath, DEFAULT_PORT);
154 }
155 
SendHttpProbe(const std::string & defaultDomain,const std::string & defaultUrl,const uint16_t defaultPort)156 NetDetectionStatus NetMonitor::SendHttpProbe(const std::string &defaultDomain, const std::string &defaultUrl,
157                                              const uint16_t defaultPort)
158 {
159     int socketType = AF_INET;
160     std::string ipAddr;
161     if (GetIpAddr(defaultDomain, ipAddr, socketType)) {
162         NETMGR_LOG_E("NetMonitor::Error at GetIpAddr");
163         return INVALID_DETECTION_STATE;
164     }
165     int32_t sockFd = socket(socketType, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP);
166     if (sockFd < 0) {
167         NETMGR_LOG_E("Create net[%{public}d] socket failed,errno[%{public}d]:%{public}s", netId_, errno,
168                      strerror(errno));
169         return INVALID_DETECTION_STATE;
170     }
171     if (SetSocketParameter(sockFd)) {
172         close(sockFd);
173         NETMGR_LOG_E("Set net[%{public}d] socket parameter error", netId_);
174         return INVALID_DETECTION_STATE;
175     }
176     if (Connect(sockFd, socketType, defaultPort, ipAddr) < 0) {
177         NETMGR_LOG_E("Connect net[%{public}d] nonblock socket:%{public}d failed", netId_, sockFd);
178         close(sockFd);
179         return INVALID_DETECTION_STATE;
180     }
181     if (Send(sockFd, defaultDomain, defaultUrl) < 0) {
182         NETMGR_LOG_E("Send http probe data to net[%{public}d] socket:%{public}d failed", netId_, sockFd);
183         close(sockFd);
184         return INVALID_DETECTION_STATE;
185     }
186     std::string probeResult;
187     if (Receive(sockFd, probeResult) < 0) {
188         NETMGR_LOG_E("Recevie probe result from net[%{public}d] socket:%{public}d failed", netId_, sockFd);
189         close(sockFd);
190         return INVALID_DETECTION_STATE;
191     }
192     close(sockFd);
193     return dealRecvResult(probeResult);
194 }
195 
Connect(int32_t sockFd,int socketType,const uint16_t port,const std::string & ipAddr)196 int32_t NetMonitor::Connect(int32_t sockFd, int socketType, const uint16_t port, const std::string &ipAddr)
197 {
198     int flags = fcntl(sockFd, F_GETFL, 0);
199     if (flags == -1 && errno == EINTR) {
200         flags = fcntl(sockFd, F_GETFL, 0);
201         if (flags == -1) {
202             NETMGR_LOG_E("Make net[%{public}d] socket:%{public}d non block failed,error[%{public}d]: %s", netId_,
203                          sockFd, errno, strerror(errno));
204             return -1;
205         }
206     }
207     uint32_t tempFlags = (uint32_t)flags | O_NONBLOCK;
208     int32_t ret = fcntl(sockFd, F_SETFL, tempFlags);
209     if (ret == -1 && errno == EINTR) {
210         ret = fcntl(sockFd, F_SETFL, tempFlags);
211         if (ret == -1) {
212             NETMGR_LOG_E("Make net[%{public}d] socket:%{public}d non block failed,error[%{public}d]: %s", netId_,
213                          sockFd, errno, strerror(errno));
214             return -1;
215         }
216     }
217     if (socketType == AF_INET6) {
218         return ConnectIpv6(sockFd, port, ipAddr);
219     } else {
220         return ConnectIpv4(sockFd, port, ipAddr);
221     }
222 }
223 
ConnectIpv4(int32_t sockFd,const uint16_t port,const std::string & ipAddr)224 int32_t NetMonitor::ConnectIpv4(int32_t sockFd, const uint16_t port, const std::string &ipAddr)
225 {
226     NETMGR_LOG_D("Net[%{public}d] connect ipv4 ip:[%{public}s] socket:%{public}d in", netId_,
227                  CommonUtils::ToAnonymousIp(ipAddr).c_str(), sockFd);
228     sockaddr_in serverAddr;
229     bzero(&serverAddr, sizeof(serverAddr));
230     serverAddr.sin_family = AF_INET;
231     serverAddr.sin_port = htons(port);
232     serverAddr.sin_addr.s_addr = inet_addr(ipAddr.c_str());
233     int32_t ret = connect(sockFd, (struct sockaddr *)&serverAddr, sizeof(serverAddr));
234     if (ret < 0) {
235         if (errno != EINPROGRESS) {
236             NETMGR_LOG_E("Connect net[%{public}d] ipv4 ip:%{public}s failed,error[%{public}d]:%{public}s", netId_,
237                          CommonUtils::ToAnonymousIp(ipAddr).c_str(), errno, strerror(errno));
238             return -1;
239         }
240     }
241     return 0;
242 }
243 
ConnectIpv6(int32_t sockFd,const uint16_t port,const std::string & ipAddr)244 int32_t NetMonitor::ConnectIpv6(int32_t sockFd, const uint16_t port, const std::string &ipAddr)
245 {
246     NETMGR_LOG_D("Net[%{public}d] connect ipv6 ip:[%{public}s] socket:%{public}d in", netId_,
247                  CommonUtils::ToAnonymousIp(ipAddr).c_str(), sockFd);
248     sockaddr_in6 serverAddr;
249     bzero(&serverAddr, sizeof(serverAddr));
250     serverAddr.sin6_family = AF_INET6;
251     serverAddr.sin6_port = htons(port);
252     inet_pton(AF_INET6, ipAddr.c_str(), &serverAddr.sin6_addr);
253     int32_t ret = connect(sockFd, (struct sockaddr *)&serverAddr, sizeof(serverAddr));
254     if (ret < 0) {
255         if (errno != EINPROGRESS) {
256             NETMGR_LOG_E("Connect net[%{public}d] ipv6 ip:%{public}s failed,error[%{public}d]:%{public}s", netId_,
257                          CommonUtils::ToAnonymousIp(ipAddr).c_str(), errno, strerror(errno));
258             return -1;
259         }
260     }
261     return 0;
262 }
263 
Wait(int32_t sockFd,uint8_t * canRead,uint8_t * canWrite)264 int32_t NetMonitor::Wait(int32_t sockFd, uint8_t *canRead, uint8_t *canWrite)
265 {
266     fd_set writeFds, readFds;
267     FD_ZERO(&readFds);
268     FD_ZERO(&writeFds);
269     if (canRead) {
270         FD_SET(sockFd, &readFds);
271     }
272     if (canWrite) {
273         FD_SET(sockFd, &writeFds);
274     }
275     struct timeval tval = {tval.tv_sec = 8, tval.tv_usec = 0};
276     int ret = select((sockFd + 1), &readFds, &writeFds, nullptr, &tval);
277     if (ret <= 0) {
278         NETMGR_LOG_E("Select net[%{public}d] failed,errno[%{public}d]:%{public}s", netId_, errno, strerror(errno));
279         return -1;
280     }
281     if (FD_ISSET(sockFd, &readFds) && canRead) {
282         *canRead = SOCKET_READY;
283     }
284     if (FD_ISSET(sockFd, &writeFds) && canWrite) {
285         *canWrite = SOCKET_READY;
286     }
287     return 0;
288 }
289 
Send(int32_t sockFd,const std::string & domain,const std::string & url)290 int32_t NetMonitor::Send(int32_t sockFd, const std::string &domain, const std::string &url)
291 {
292     uint8_t canWrite = SOCKET_NOT_READY;
293     int32_t ret = Wait(sockFd, nullptr, &canWrite);
294     if (ret < 0 || canWrite != SOCKET_READY) {
295         NETMGR_LOG_E("Net[%{public}d] socket not ready to send data,ret:%{public}d, canWrite:%{public}d", netId_, ret,
296                      canWrite);
297         return -1;
298     }
299     std::string sendData = "GET /" + url + " HTTP/1.1\r\n";
300     sendData.append("Host: " + domain + "\r\n\r\n");
301     const char *writeBuf = sendData.c_str();
302     int32_t bufSize = static_cast<int32_t>(sendData.size());
303     int32_t written = 0;
304     int32_t retry = 0;
305     while (bufSize > 0) {
306         written = send(sockFd, writeBuf, bufSize, 0);
307         if (written < 0) {
308             if (errno == EAGAIN && retry < MAX_SEND_RETRY) {
309                 ++retry;
310                 NETMGR_LOG_W("Net[%{public}d] try to resend the data to sokcet:%{public}d for the :%{public}d times",
311                              netId_, sockFd, retry);
312                 continue;
313             }
314             NETMGR_LOG_E("Net[%{public}d] Send data to socket:%{public}d failed, errno[%{public}d]:%{public}s", netId_,
315                          sockFd, errno, strerror(errno));
316             return -1;
317         }
318         if (written == 0) {
319             break;
320         }
321         writeBuf += written;
322         bufSize -= written;
323     }
324     return 0;
325 }
326 
Receive(int32_t sockFd,std::string & probResult)327 int32_t NetMonitor::Receive(int32_t sockFd, std::string &probResult)
328 {
329     uint8_t canRead = SOCKET_NOT_READY;
330     int32_t ret = Wait(sockFd, &canRead, nullptr);
331     if (ret < 0 || canRead != SOCKET_READY) {
332         NETMGR_LOG_E("Net[%{public}d] socket not ready to read data, ret:%{public}d, canRead:%{public}d", netId_, ret,
333                      canRead);
334         return -1;
335     }
336     char buff[MAX_RECIVE_SIZE] = {0};
337     int32_t recvBytes = recv(sockFd, buff, MAX_RECIVE_SIZE, 0);
338     if (recvBytes <= 0) {
339         NETMGR_LOG_E("Receive net[%{public}d] data from socket failed,errno[%{public}d]:%{public}s", netId_, errno,
340                      strerror(errno));
341         return -1;
342     }
343     probResult = std::string(buff, recvBytes);
344     return 0;
345 }
346 
SetSocketParameter(int32_t sockFd)347 int32_t NetMonitor::SetSocketParameter(int32_t sockFd)
348 {
349     std::unique_ptr<nmd::FwmarkClient> fwmarkClient = std::make_unique<nmd::FwmarkClient>();
350     if (fwmarkClient->BindSocket(sockFd, netId_) < 0) {
351         NETMGR_LOG_E("Error at bind net[%{public}d] socket", netId_);
352         struct EventInfo eventInfo = {.socketFd = sockFd,
353                                       .errorType = static_cast<int32_t>(FAULT_BIND_SOCKET_FAILED),
354                                       .errorMsg =
355                                           std::string("Bind socket:").append(std::to_string(sockFd)).append(" failed")};
356         EventReport::SendMonitorFaultEvent(eventInfo);
357         return -1;
358     }
359     struct timeval timeout;
360     timeout.tv_sec = SOCKET_TIMEOUT;
361     timeout.tv_usec = 0;
362     if (setsockopt(sockFd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)) ||
363         setsockopt(sockFd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout))) {
364         NETMGR_LOG_E("Error at set net[%{public}d] socket timeout,error[%{public}d]:%{public}s", netId_, errno,
365                      strerror(errno));
366         return -1;
367     }
368     return 0;
369 }
370 
dealRecvResult(const std::string & strResponse)371 NetDetectionStatus NetMonitor::dealRecvResult(const std::string &strResponse)
372 {
373     std::string urlRedirect = "";
374     int32_t retCode = GetUrlRedirectFromResponse(strResponse, urlRedirect);
375     int32_t statusCode = GetStatusCodeFromResponse(strResponse);
376     portalUrlRedirect_ = urlRedirect;
377     NETMGR_LOG_D("statusCode[%{public}d], retCode[%{public}d]", statusCode, retCode);
378     if ((statusCode == OK || (statusCode >= BAD_REQUEST && statusCode <= CLIENT_ERROR_MAX)) &&
379         retCode > PORTAL_CONTENT_LENGTH_MIN) {
380         if (retCode > -1) {
381             return CAPTIVE_PORTAL_STATE;
382         }
383         return INVALID_DETECTION_STATE;
384     } else if (statusCode == NO_CONTENT) {
385         return VERIFICATION_STATE;
386     } else if ((statusCode != NO_CONTENT) && (statusCode >= CREATED) && (statusCode <= URL_REDIRECT_MAX)) {
387         if (retCode > -1) {
388             return CAPTIVE_PORTAL_STATE;
389         }
390         return INVALID_DETECTION_STATE;
391     }
392     return INVALID_DETECTION_STATE;
393 }
394 
GetStatusCodeFromResponse(const std::string & strResponse)395 int32_t NetMonitor::GetStatusCodeFromResponse(const std::string &strResponse)
396 {
397     if (strResponse.empty()) {
398         NETMGR_LOG_E("strResponse is empty");
399         return -1;
400     }
401 
402     std::string::size_type newLinePos = strResponse.find("\r\n");
403     if (newLinePos == std::string::npos) {
404         NETMGR_LOG_E("StrResponse did not find the response line!");
405         return -1;
406     }
407     std::string statusLine = strResponse.substr(0, newLinePos);
408     std::string::size_type spacePos = statusLine.find(" ");
409     if (spacePos == std::string::npos) {
410         NETMGR_LOG_E("No spaces found in the response line!");
411         return -1;
412     }
413     std::string strStatusCode = statusLine.substr(spacePos + 1, statusLine.length() - 1);
414     std::string::size_type pos = strStatusCode.find(" ");
415     if (pos == std::string::npos) {
416         NETMGR_LOG_E("No other space was found in the response line!");
417         return -1;
418     }
419     strStatusCode.resize(pos);
420     if (strStatusCode.empty()) {
421         NETMGR_LOG_E("String status code is empty!");
422         return -1;
423     }
424 
425     int32_t statusCode = std::stoi(strStatusCode);
426     return statusCode;
427 }
428 
GetUrlRedirectFromResponse(const std::string & strResponse,std::string & urlRedirect)429 int32_t NetMonitor::GetUrlRedirectFromResponse(const std::string &strResponse, std::string &urlRedirect)
430 {
431     if (strResponse.empty()) {
432         NETMGR_LOG_E("strResponse is empty");
433         return -1;
434     }
435 
436     std::string::size_type startPos = strResponse.find(PORTAL_URL_REDIRECT_FIRST_CASE);
437     if (startPos != std::string::npos) {
438         startPos += strlen(PORTAL_URL_REDIRECT_FIRST_CASE);
439         std::string::size_type endPos = strResponse.find(PORTAL_END_STR, startPos);
440         if (endPos != std::string::npos) {
441             urlRedirect = strResponse.substr(startPos, endPos - startPos + strlen(PORTAL_END_STR));
442         }
443         return 0;
444     }
445 
446     startPos = strResponse.find(PORTAL_URL_REDIRECT_SECOND_CASE);
447     if (startPos != std::string::npos) {
448         startPos += strlen(PORTAL_URL_REDIRECT_SECOND_CASE);
449         std::string::size_type endPos = strResponse.find(PORTAL_END_STR, startPos);
450         if (endPos != std::string::npos) {
451             urlRedirect = strResponse.substr(startPos, endPos - startPos + strlen(PORTAL_END_STR));
452         }
453         startPos = strResponse.find(CONTENT_STR);
454         return std::atoi(strResponse.substr(startPos + strlen(CONTENT_STR), NET_CONTENT_LENGTH).c_str());
455     }
456     return -1;
457 }
458 
GetIpAddr(const std::string & domain,std::string & ip_addr,int & socketType)459 int32_t NetMonitor::GetIpAddr(const std::string &domain, std::string &ip_addr, int &socketType)
460 {
461     std::vector<AddrInfo> result;
462     AddrInfo hints = {};
463     std::string serverName;
464     if (NetsysController::GetInstance().GetAddrInfo(domain, serverName, hints, netId_, result) < 0) {
465         NETMGR_LOG_E("Get net[%{public}d] address info failed,errno[%{public}d]:%{public}s", netId_, errno,
466                      strerror(errno));
467         return -1;
468     }
469     if (result.empty()) {
470         NETMGR_LOG_E("Get net[%{public}d] address info return nullptr result", netId_);
471         return -1;
472     }
473     char ip[DOMAINIPADDR] = {0};
474     for (auto &node : result) {
475         if (node.aiFamily != AF_INET) {
476             continue;
477         }
478         if (!inet_ntop(AF_INET, &node.aiAddr.sin.sin_addr, ip, sizeof(ip))) {
479             continue;
480         }
481         ip_addr = ip;
482         socketType = AF_INET;
483         NETMGR_LOG_D("Get net[%{public}d] monitor ip:%{public}s", netId_, CommonUtils::ToAnonymousIp(ip_addr).c_str());
484         return 0;
485     }
486     if (result[0].aiFamily == AF_INET6) {
487         inet_ntop(AF_INET6, &result[0].aiAddr.sin6.sin6_addr, ip, sizeof(ip));
488         ip_addr = ip;
489         socketType = AF_INET6;
490     }
491     NETMGR_LOG_D("Get net[%{public}d] monitor ip:%{public}s", netId_, CommonUtils::ToAnonymousIp(ip_addr).c_str());
492     return 0;
493 }
494 
GetDefaultNetDetectionUrlFromCfg(std::string & strUrl)495 int32_t NetMonitor::GetDefaultNetDetectionUrlFromCfg(std::string &strUrl)
496 {
497     int32_t ret = 0;
498     std::ifstream file(URL_CFG_FILE);
499     if (!file.is_open()) {
500         NETMGR_LOG_E("Open file failed (%{public}s)", strerror(errno));
501         ret = -1;
502         return ret;
503     }
504 
505     std::ostringstream oss;
506     oss << file.rdbuf();
507     std::string content = oss.str();
508     auto index = content.find_last_of(SPACE_STR);
509     strUrl = content.substr(index + 1);
510     if (strUrl.empty()) {
511         NETMGR_LOG_E("get netdetectionurl is empty");
512         ret = -1;
513     }
514     strUrl.erase(std::remove(strUrl.begin(), strUrl.end(), NEW_LINE_STR), strUrl.end());
515     NETMGR_LOG_D("GetDefaultNetDetectionUrl is : %{public}s", strUrl.c_str());
516     return ret;
517 }
518 
ParseUrl(const std::string & url,std::string & domain,std::string & urlPath)519 int32_t NetMonitor::ParseUrl(const std::string &url, std::string &domain, std::string &urlPath)
520 {
521     std::regex reg_domain_port("/");
522     std::cregex_token_iterator itrBegin(url.c_str(), url.c_str() + url.size(), reg_domain_port, -1);
523     std::cregex_token_iterator itrEnd;
524     int32_t i = 0;
525     for (std::cregex_token_iterator itr = itrBegin; itr != itrEnd; ++itr) {
526         i++;
527         if (i == DOMAIN_POSITION) {
528             domain = *itr;
529         } else if (i == URLPATH_POSITION) {
530             urlPath = *itr;
531         }
532     }
533     return (domain.empty() || urlPath.empty()) ? -1 : 0;
534 }
535 } // namespace NetManagerStandard
536 } // namespace OHOS
537