105 lines
3 KiB
C++
105 lines
3 KiB
C++
//
|
|
// Copyright (C) 2015 The Android Open Source Project
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
//
|
|
|
|
#include "shill/dns_server_proxy.h"
|
|
|
|
#include <map>
|
|
|
|
#include <base/bind.h>
|
|
#include <base/strings/stringprintf.h>
|
|
|
|
#include "shill/logging.h"
|
|
#include "shill/process_manager.h"
|
|
|
|
using std::string;
|
|
using std::vector;
|
|
|
|
namespace shill {
|
|
|
|
namespace {
|
|
const char kDnsmasqPath[] = "/system/bin/dnsmasq";
|
|
const char kDnsmasqPidFilePath[] = "/data/misc/shill/dnsmasq.pid";
|
|
const char kDnsmasqUser[] = "system";
|
|
const char kDnsmasqGroup[] = "system";
|
|
const int kInvalidPID = -1;
|
|
}
|
|
|
|
DNSServerProxy::DNSServerProxy(const vector<string>& dns_servers)
|
|
: process_manager_(ProcessManager::GetInstance()),
|
|
pid_(kInvalidPID),
|
|
dns_servers_(dns_servers) {}
|
|
|
|
DNSServerProxy::~DNSServerProxy() {
|
|
if (pid_ != kInvalidPID) {
|
|
Stop();
|
|
}
|
|
}
|
|
|
|
bool DNSServerProxy::Start() {
|
|
if (pid_ != kInvalidPID) {
|
|
LOG(ERROR) << __func__ << ": already started";
|
|
return false;
|
|
}
|
|
// Setup command line arguments for dnsmasq.
|
|
vector<string> args;
|
|
args.push_back("--no-hosts");
|
|
args.push_back("--listen-address=127.0.0.1");
|
|
args.push_back("--no-resolv");
|
|
args.push_back("--keep-in-foreground");
|
|
args.push_back(base::StringPrintf("--user=%s", kDnsmasqUser));
|
|
args.push_back(base::StringPrintf("--group=%s", kDnsmasqGroup));
|
|
for (const auto& server : dns_servers_) {
|
|
args.push_back(base::StringPrintf("--server=%s", server.c_str()));
|
|
}
|
|
args.push_back(base::StringPrintf("--pid-file=%s", kDnsmasqPidFilePath));
|
|
// Start dnsmasq.
|
|
// TODO(zqiu): start dnsmasq with Minijail when the latter is working on
|
|
// Android (b/24572800).
|
|
pid_t pid =
|
|
process_manager_->StartProcess(
|
|
FROM_HERE,
|
|
base::FilePath(kDnsmasqPath),
|
|
args,
|
|
std::map<string, string>(), // No environment variables needed.
|
|
true, // Terminate with parent.
|
|
base::Bind(&DNSServerProxy::OnProcessExited,
|
|
weak_factory_.GetWeakPtr()));
|
|
if (pid < 0) {
|
|
return false;
|
|
}
|
|
|
|
pid_ = pid;
|
|
LOG(INFO) << "Spawned " << kDnsmasqPath << " with pid: " << pid_;
|
|
return true;
|
|
}
|
|
|
|
void DNSServerProxy::Stop() {
|
|
if (pid_ == kInvalidPID) {
|
|
LOG(ERROR) << __func__ << ": already stopped";
|
|
return;
|
|
}
|
|
process_manager_->StopProcess(pid_);
|
|
}
|
|
|
|
void DNSServerProxy::OnProcessExited(int exit_status) {
|
|
CHECK(pid_);
|
|
if (exit_status != EXIT_SUCCESS) {
|
|
LOG(WARNING) << "pid " << pid_ << " exit status " << exit_status;
|
|
}
|
|
pid_ = kInvalidPID;
|
|
}
|
|
|
|
} // namespace shill
|