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