const char * const OEM_SCRIPT_PATH = "/system/bin/oem-iptables-init.sh";
const char * const IPTABLES_PATH = "/system/bin/iptables";
const char * const IP6TABLES_PATH = "/system/bin/ip6tables";
+const char * const IPTABLES_RESTORE_PATH = "/system/bin/iptables-restore";
+const char * const IP6TABLES_RESTORE_PATH = "/system/bin/ip6tables-restore";
const char * const TC_PATH = "/system/bin/tc";
const char * const IP_PATH = "/system/bin/ip";
const char * const ADD = "add";
std::list<const char*> argsList;
argsList.push_back(NULL);
const char* arg;
+
+ // Wait to avoid failure due to another process holding the lock
+ argsList.push_back("-w");
+
do {
arg = va_arg(args, const char *);
argsList.push_back(arg);
return res;
}
-int writeFile(const char *path, const char *value, int size) {
- int fd = open(path, O_WRONLY);
- if (fd < 0) {
- ALOGE("Failed to open %s: %s", path, strerror(errno));
- return -1;
- }
+static int execIptablesRestoreCommand(const char *cmd, const std::string& commands) {
+ const char *argv[] = {
+ cmd,
+ "--noflush", // Don't flush the whole table.
+ "-w", // Wait instead of failing if the lock is held.
+ };
+ AndroidForkExecvpOption opt[1] = {
+ {
+ .opt_type = FORK_EXECVP_OPTION_INPUT,
+ .opt_input.input = reinterpret_cast<const uint8_t*>(commands.c_str()),
+ .opt_input.input_len = commands.size(),
+ }
+ };
- if (write(fd, value, size) != size) {
- ALOGE("Failed to write %s: %s", path, strerror(errno));
- close(fd);
+ int status = 0;
+ int res = android_fork_execvp_ext(
+ ARRAY_SIZE(argv), (char**)argv, &status, false /* ignore_int_quit */, LOG_NONE,
+ false /* abbreviated */, NULL /* file_path */, opt, ARRAY_SIZE(opt));
+ if (res || status) {
+ ALOGE("%s failed with res=%d, status=%d", argv[0], res, status);
return -1;
}
- close(fd);
+
return 0;
}
-int readFile(const char *path, char *buf, int *sizep)
-{
- int fd = open(path, O_RDONLY);
- int size;
-
- if (fd < 0) {
- ALOGE("Failed to open %s: %s", path, strerror(errno));
- return -1;
+int execIptablesRestore(IptablesTarget target, const std::string& commands) {
+ int res = 0;
+ if (target == V4 || target == V4V6) {
+ res |= execIptablesRestoreCommand(IPTABLES_RESTORE_PATH, commands);
}
-
- size = read(fd, buf, *sizep);
- if (size < 0) {
- ALOGE("Failed to write %s: %s", path, strerror(errno));
- close(fd);
- return -1;
+ if (target == V6 || target == V4V6) {
+ res |= execIptablesRestoreCommand(IP6TABLES_RESTORE_PATH, commands);
}
- *sizep = size;
- close(fd);
- return 0;
+ return res;
}
/*