Android之网络-netd分析
2022-01-21 本文已影响0人
锄禾豆
简介
Netd 就是Network Daemon 的缩写,表示Network守护进程。
Netd负责跟一些涉及网络的配置,操作,管理,查询等相关的功能实现.
例如:带宽控制 (Bandwidth),流量统计,网络地址转换(NAT),个人局域网(pan),
PPP链接,soft-ap,共享上网(Tether), 配置路由表,interface配置管理等
代码路径
system/netd
system/core/libsysutils
system/core/include/sysutils
注:
10.0
一.netd进程介绍
1.查看进程netd
jj:/dev/socket # ps -A | grep netd
root 418 1 2389212 7704 binder_ioctl_write_read 0 S netd
说明支持binder通信
2.查看netd.rc
service netd /system/bin/netd
class main
socket dnsproxyd stream 0660 root inet
socket mdns stream 0660 root system
socket fwmarkd stream 0660 root inet
onrestart restart zygote
onrestart restart zygote_secondary
# b/121354779: netd itself is not updatable, but on startup it dlopen()s the resolver library
# from the DNS resolver APEX. Mark it as updatable so init won't start it until all APEX
# packages are ready.
updatable
从netd.rc文件看,系统进程netd,跨进程的方式有socket:dnsproxyd\mdns\fwmarkd。
可查这些socket:/dev/socket/**
3.小结
netd支持binder和socket通信
4.具体实现:main.cpp
int main() {
Stopwatch s;
gLog.info("netd 1.0 starting");
android::net::process::removePidFile(PID_FILE_PATH);
android::net::process::blockSigPipe();
// Before we do anything that could fork, mark CLOEXEC the UNIX sockets that we get from init.
// FrameworkListener does this on initialization as well, but we only initialize these
// components after having initialized other subsystems that can fork.
for (const auto& sock :
{DNSPROXYLISTENER_SOCKET_NAME, FwmarkServer::SOCKET_NAME, MDnsSdListener::SOCKET_NAME}) {
setCloseOnExec(sock);
}
// Before we start any threads, populate the resolver stub pointers.
resolv_stub_init();
// Make sure BPF programs are loaded before doing anything
while (!android::base::WaitForProperty("bpf.progs_loaded", "1",
std::chrono::seconds(5))) {
ALOGD("netd waited 5s for bpf.progs_loaded, still waiting...");
}
NetlinkManager *nm = NetlinkManager::Instance();
if (nm == nullptr) {
ALOGE("Unable to create NetlinkManager");
exit(1);
};
gCtls = new android::net::Controllers();
gCtls->init();
if (nm->start()) {
ALOGE("Unable to start NetlinkManager (%s)", strerror(errno));
exit(1);
}
std::unique_ptr<NFLogListener> logListener;
{
auto result = makeNFLogListener();
if (!isOk(result)) {
ALOGE("Unable to create NFLogListener: %s", toString(result).c_str());
exit(1);
}
logListener = std::move(result.value());
auto status = gCtls->wakeupCtrl.init(logListener.get());
if (!isOk(result)) {
gLog.error("Unable to init WakeupController: %s", toString(result).c_str());
// We can still continue without wakeup packet logging.
}
}
// Set local DNS mode, to prevent bionic from proxying
// back to this service, recursively.
// TODO: Check if we could remove it since resolver cache no loger
// checks this environment variable after aosp/838050.
setenv("ANDROID_DNS_MODE", "local", 1);
// Note that only call initDnsResolver after gCtls initializing.
// 初始化SocketServer:dnsproxyd
if (!initDnsResolver()) {
ALOGE("Unable to init resolver");
exit(1);
}
MDnsSdListener mdnsl;
if (mdnsl.startListener()) {//初始化SocketServer:mdns
ALOGE("Unable to start MDnsSdListener (%s)", strerror(errno));
exit(1);
}
FwmarkServer fwmarkServer(&gCtls->netCtrl, &gCtls->eventReporter, &gCtls->trafficCtrl);
if (fwmarkServer.startListener()) {//初始化SocketServer:fwmarkd
ALOGE("Unable to start FwmarkServer (%s)", strerror(errno));
exit(1);
}
Stopwatch subTime;
status_t ret;
if ((ret = NetdNativeService::start()) != android::OK) {//建立binder service:netd
ALOGE("Unable to start NetdNativeService: %d", ret);
exit(1);
}
gLog.info("Registering NetdNativeService: %.1fms", subTime.getTimeAndReset());
android::net::process::ScopedPidFile pidFile(PID_FILE_PATH);
// Now that netd is ready to process commands, advertise service
// availability for HAL clients.
NetdHwService mHwSvc;
if ((ret = mHwSvc.start()) != android::OK) {
ALOGE("Unable to start NetdHwService: %d", ret);
exit(1);
}
gLog.info("Registering NetdHwService: %.1fms", subTime.getTimeAndReset());
gLog.info("Netd started in %dms", static_cast<int>(s.timeTaken()));
IPCThreadState::self()->joinThreadPool();
gLog.info("netd exiting");
exit(0);
}
DnsProxyListener负责socket:dnsproxyd
MDnsSdListener负责socket:mdns
FwmarkServer负责socket:fwmarkd
NetdNativeService负责binder:netd
二.重点简介netd服务
1.adb查看
adb shell dumpsys netd
2.NetNativeService分析
1)NetNativeService继承BinderService。查看NetdNativeService.h
class NetdNativeService : public BinderService<NetdNativeService>
static char const* getServiceName() { return "netd"; }
2)NetNativeService::start()
status_t NetdNativeService::start() {
IPCThreadState::self()->disableBackgroundScheduling(true);
const status_t ret = BinderService<NetdNativeService>::publish();//注册服务
if (ret != android::OK) {
return ret;
}
sp<ProcessState> ps(ProcessState::self());
ps->startThreadPool();
ps->giveThreadPoolName();
return android::OK;
}
查看BinderService.h可知,从模板类中获取名称再加入到ServiceManager服务中
template<typename SERVICE>
class BinderService
{
public:
static status_t publish(bool allowIsolated = false,
int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
sp<IServiceManager> sm(defaultServiceManager());
return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated,
dumpFlags);
}
···
}
NetNativeService建立binder通信,客户端可以正常调用
3)这样NetworkManagementService可通过binder与netd通信
客户端获取方式:
INetd netdInstance = INetd.Stub.asInterface(
ServiceManager.getService(Context.NETD_SERVICE));
三.参考学习
https://blog.csdn.net/ltm157/article/details/24799351
https://www.kancloud.cn/alex_wsc/android-wifi-nfc-gps/413624
https://yjy239.github.io/2020/11/29/android-chong-xue-xi-lie-networkmanagementservice-netd-zai-dns-cha-xun-de-zhi-neng/
https://sniffer.site/2018/12/18/android-netd%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86%E8%AF%A6%E8%A7%A3/