• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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 "iptables_wrapper.h"
17 
18 #include <unistd.h>
19 
20 #include "datetime_ex.h"
21 #include "net_manager_constants.h"
22 #include "netmanager_base_common_utils.h"
23 #include "netnative_log_wrapper.h"
24 
25 #ifdef UNITTEST_FORBID_FFRT
26 #undef UNITTEST_FORBID_FFRT
27 #endif
28 #define UNITTEST_FORBID_FFRT 1
29 
30 namespace OHOS {
31 namespace nmd {
32 using namespace NetManagerStandard;
33 namespace {
34 constexpr const char *IPATBLES_CMD_PATH = "/system/bin/iptables";
35 constexpr const char *IP6TABLES_CMD_PATH = "/system/bin/ip6tables";
36 } // namespace
37 
IptablesWrapper()38 IptablesWrapper::IptablesWrapper()
39 {
40     isRunningFlag_ = true;
41     isIptablesSystemAccess_ = access(IPATBLES_CMD_PATH, F_OK) == 0;
42     isIp6tablesSystemAccess_ = access(IP6TABLES_CMD_PATH, F_OK) == 0;
43 
44     iptablesWrapperFfrtQueue_ = std::make_shared<ffrt::queue>("IptablesWrapper");
45 }
46 
~IptablesWrapper()47 IptablesWrapper::~IptablesWrapper()
48 {
49     isRunningFlag_ = false;
50     iptablesWrapperFfrtQueue_.reset();
51 }
52 
ExecuteCommand(const std::string & command)53 void IptablesWrapper::ExecuteCommand(const std::string &command)
54 {
55     std::string cmdWithWait = command + " -w 5 ";
56     NETNATIVE_LOGI("ExecuteCommand %{public}s", CommonUtils::AnonymousIpInStr(cmdWithWait).c_str());
57     if (CommonUtils::ForkExec(cmdWithWait) == NETMANAGER_ERROR) {
58         NETNATIVE_LOGE("run exec faild");
59     }
60 }
61 
ExecuteCommandForRes(const std::string & command)62 void IptablesWrapper::ExecuteCommandForRes(const std::string &command)
63 {
64     std::string cmdWithWait = command + " -w 5 ";
65     NETNATIVE_LOGI("ExecuteCommandForRes %{public}s", CommonUtils::AnonymousIpInStr(cmdWithWait).c_str());
66     if (CommonUtils::ForkExec(cmdWithWait, &result_) == NETMANAGER_ERROR) {
67         NETNATIVE_LOGE("run exec faild");
68     }
69 }
70 
RunCommand(const IpType & ipType,const std::string & command)71 int32_t IptablesWrapper::RunCommand(const IpType &ipType, const std::string &command)
72 {
73     NETNATIVE_LOG_D("IptablesWrapper::RunCommand, ipType:%{public}d", ipType);
74     if (!iptablesWrapperFfrtQueue_) {
75         NETNATIVE_LOGE("FFRT Init Fail");
76         return NETMANAGER_ERROR;
77     }
78 
79     if (isIptablesSystemAccess_ && (ipType == IPTYPE_IPV4 || ipType == IPTYPE_IPV4V6)) {
80         std::string cmd = std::string(IPATBLES_CMD_PATH) + " " + command;
81 #if UNITTEST_FORBID_FFRT // Forbid FFRT for unittest, which will cause crash in destructor process
82         ExecuteCommand(cmd);
83 #else
84         std::function<void()> executeCommand = std::bind(&IptablesWrapper::ExecuteCommand, shared_from_this(), cmd);
85         iptablesWrapperFfrtQueue_->submit(executeCommand);
86 #endif // UNITTEST_FORBID_FFRT
87     }
88 
89     if (isIp6tablesSystemAccess_ && (ipType == IPTYPE_IPV6 || ipType == IPTYPE_IPV4V6)) {
90         std::string cmd = std::string(IP6TABLES_CMD_PATH) + " " + command;
91 #if UNITTEST_FORBID_FFRT // Forbid FFRT for unittest, which will cause crash in destructor process
92         ExecuteCommand(cmd);
93 #else
94         std::function<void()> executeCommand = std::bind(&IptablesWrapper::ExecuteCommand, shared_from_this(), cmd);
95         iptablesWrapperFfrtQueue_->submit(executeCommand);
96 #endif // UNITTEST_FORBID_FFRT
97     }
98 
99     return NetManagerStandard::NETMANAGER_SUCCESS;
100 }
101 
RunCommandForRes(const IpType & ipType,const std::string & command)102 std::string IptablesWrapper::RunCommandForRes(const IpType &ipType, const std::string &command)
103 {
104     NETNATIVE_LOGI("IptablesWrapper::RunCommandForRes, ipType:%{public}d", ipType);
105     if (!iptablesWrapperFfrtQueue_) {
106         NETNATIVE_LOGE("FFRT Init Fail");
107         return result_;
108     }
109 
110     if (ipType == IPTYPE_IPV4 || ipType == IPTYPE_IPV4V6) {
111         std::string cmd = std::string(IPATBLES_CMD_PATH) + " " + command;
112         std::function<void()> executeCommandForRes =
113             std::bind(&IptablesWrapper::ExecuteCommandForRes, shared_from_this(), cmd);
114 
115         int64_t start = GetTickCount();
116 #if UNITTEST_FORBID_FFRT // Forbid FFRT for unittest, which will cause crash in destructor process
117         executeCommandForRes();
118 #else
119         ffrt::task_handle RunCommandForResTaskIpv4 = iptablesWrapperFfrtQueue_->submit_h(executeCommandForRes);
120         iptablesWrapperFfrtQueue_->wait(RunCommandForResTaskIpv4);
121 #endif // UNITTEST_FORBID_FFRT
122         NETNATIVE_LOGI("FFRT cost:%{public}lld ms", static_cast<long long>(GetTickCount() - start));
123     }
124 
125     if (ipType == IPTYPE_IPV6 || ipType == IPTYPE_IPV4V6) {
126         std::string cmd = std::string(IP6TABLES_CMD_PATH) + " " + command;
127         std::function<void()> executeCommandForRes =
128             std::bind(&IptablesWrapper::ExecuteCommandForRes, shared_from_this(), cmd);
129 
130         int64_t start = GetTickCount();
131 #if UNITTEST_FORBID_FFRT // Forbid FFRT for unittest, which will cause crash in destructor process
132         executeCommandForRes();
133 #else
134         ffrt::task_handle RunCommandForResTaskIpv6 = iptablesWrapperFfrtQueue_->submit_h(executeCommandForRes);
135         iptablesWrapperFfrtQueue_->wait(RunCommandForResTaskIpv6);
136 #endif // UNITTEST_FORBID_FFRT
137         NETNATIVE_LOGI("FFRT cost:%{public}lld ms", static_cast<long long>(GetTickCount() - start));
138     }
139 
140     return result_;
141 }
142 
RunMutipleCommands(const IpType & ipType,const std::vector<std::string> & commands)143 int32_t IptablesWrapper::RunMutipleCommands(const IpType &ipType, const std::vector<std::string> &commands)
144 {
145     NETNATIVE_LOG_D("IptablesWrapper::RunMutipleCommands, ipType:%{public}d", ipType);
146     if (!iptablesWrapperFfrtQueue_) {
147         NETNATIVE_LOGE("FFRT Init Fail");
148         return NETMANAGER_ERROR;
149     }
150 
151     for (const std::string& command : commands) {
152         if (isIptablesSystemAccess_ && (ipType == IPTYPE_IPV4 || ipType == IPTYPE_IPV4V6)) {
153             std::string cmd = std::string(IPATBLES_CMD_PATH) + " " + command;
154             std::function<void()> executeCommand = std::bind(&IptablesWrapper::ExecuteCommand, shared_from_this(), cmd);
155 #if UNITTEST_FORBID_FFRT // Forbid FFRT for unittest, which will cause crash in destructor process
156             executeCommand();
157 #else
158             iptablesWrapperFfrtQueue_->submit(executeCommand);
159 #endif
160         }
161 
162         if (isIp6tablesSystemAccess_ && (ipType == IPTYPE_IPV6 || ipType == IPTYPE_IPV4V6)) {
163             std::string cmd = std::string(IP6TABLES_CMD_PATH) + " " + command;
164             std::function<void()> executeCommand = std::bind(&IptablesWrapper::ExecuteCommand, shared_from_this(), cmd);
165 #if UNITTEST_FORBID_FFRT // Forbid FFRT for unittest, which will cause crash in destructor process
166             executeCommand();
167 #else
168             iptablesWrapperFfrtQueue_->submit(executeCommand);
169 #endif
170         }
171     }
172 
173     return NetManagerStandard::NETMANAGER_SUCCESS;
174 }
175 
176 } // namespace nmd
177 } // namespace OHOS
178