美文网首页
Android之网络-netd分析

Android之网络-netd分析

作者: 锄禾豆 | 来源:发表于2022-01-21 12:49 被阅读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/
    

    相关文章

      网友评论

          本文标题:Android之网络-netd分析

          本文链接:https://www.haomeiwen.com/subject/kpxshrtx.html