android netd守护进程机制 --- Java层分析

前言:

Netd是Android系统中专门负责网络管理的守护进程。NetD是网络管家,封装了复杂的底层各种类型的网络

(NAT,PLAN,PPP,SOFTAP,TECHER,ETHO,MDNS等),隔离了底层网络接口的差异,给Framework

提供了统一调用接口,简化了网络的使用。主要工作分为2个部分:

1,接收并处理来自Framework层中NetworkManagementService或NsdService的命令。这些命令最终由Netd中

对应的Command对象去处理。

2,接收并解析来自Kernel的UEvent消息,然后再转发给Framework层中对应Service去处理。

Netd位于Framework层和Kernel层之间,它是android系统中网络相关消息和命令转发及处理的中枢。本文基于android 6.0

1,进程启动

Netd进程由init进程启动, 其在init.rc文件的配置如下:

service netd /system/bin/netd
    class main
    socket netd stream 0660 root system
    socket dnsproxyd stream 0660 root inet
    socket mdns stream 0660 root system
    socket fwmarkd stream 0660 root inet

由此可见,有四个socket,具体作用如下,

netd socket: NetworkManagementService和netd进程进行进程间通信;

mdns socket: NsdService和netd进程进行进程间通信;

fwmarkd socket: kernel和netd进程进行通信;

当然,这四个socket之间是相互独立的。

主要代码路径如下,

system\netd


Netd进程的入口方法main.cpp的main方法,主要代码如下,

CommandListener *cl;
NetlinkManager *nm;
DnsProxyListener *dpl;
MDnsSdListener *mdnsl;
FwmarkServer* fwmarkServer;
•••
cl = new CommandListener();//创建CommandListener对象

nm->setBroadcaster((SocketListener *) cl);

 if (nm->start()) { //启动NetlinkManager
 •••
setenv("ANDROID_DNS_MODE", "local", 1); //Netd设置环境变量ANDROID_DNS_MODE为"local"
dpl = new DnsProxyListener(CommandListener::sNetCtrl); //创建DnsProxyListener对象
if (dpl->startListener()) {//开始监听dnsproxyd socket
•••
mdnsl = new MDnsSdListener();//创建MdnsSdListener对象
if (mdnsl->startListener()) {//开始监听mdns socket
•••
fwmarkServer = new FwmarkServer(CommandListener::sNetCtrl);
if (fwmarkServer->startListener()) {// 监听fwmarkd socket
•••
if (cl->startListener()) {// 监听netd socket
•••

主要是启动了4个子线程,监听4个socket。还启动了NetlinkManage, 负责接收并解析来自Kernel的UEvent消息。

2, Java层分析

Framework主要有关的类如下,

/frameworks/base/services/core/java/com/android/server/

NetworkManagementService.java

NativeDaemonConnector.java

这2个类都运行于系统服务所在的进程当中。

2.1 启动

SystemServer.java中启动NetworkManagementService有关代码如下,

networkManagement = NetworkManagementService.create(context);
ServiceManager.addService(Context.NETWORKMANAGEMENT_SERVICE, networkManagement);

NetworkManagementService的create方法如下,

public static NetworkManagementService create(Context context) throws InterruptedException {
        return create(context, NETD_SOCKET_NAME);
}

NETD_SOCKET_NAME是netd socket,定义如下,

private static final String NETD_SOCKET_NAME = "netd";

create方法主要代码如下,

final NetworkManagementService service = new NetworkManagementService(context, socket);
service.mThread.start();//启动线程

NetworkManagementService构造方法主要代码如下,

mConnector = new NativeDaemonConnector(
new NetdCallbackReceiver(), socket, 10, NETD_TAG, 160, wl, FgThread.get().getLooper());
mThread = new Thread(mConnector, NETD_TAG);//创建名为NetdConnector的子线程

首先构造NetdCallbackReceiver对象, NetdCallbackReceiver是一个内部类,主要用于处理来自 netd进程的消息。

然后利用NetdCallbackReceiver对象构造NativeDaemonConnector,

NativeDaemonConnector本质就是一个线程,定义如下,

final class NativeDaemonConnector implements Runnable, Handler.Callback, Watchdog.Monitor {

mThread其实就是指NativeDaemonConnector线程, service.mThread.start()这句话就是调用NativeDaemonConnector的run方法。

首先看NativeDaemonConnector构造方法,

NativeDaemonConnector(INativeDaemonConnectorCallbacks callbacks, String socket,
            int responseQueueSize, String logTag, int maxLogSize, PowerManager.WakeLock wl,
            Looper looper) {
        mCallbacks = callbacks; //跨进程回调
        mSocket = socket;//netd socket
        mResponseQueue = new ResponseQueue(responseQueueSize);//应答消息处理
        mWakeLock = wl;
        if (mWakeLock != null) {
            mWakeLock.setReferenceCounted(true);
        }
        mLooper = looper;
        mSequenceNumber = new AtomicInteger(0);
        TAG = logTag != null ? logTag : "NativeDaemonConnector";
        mLocalLog = new LocalLog(maxLogSize);
    }

NativeDaemonConnector的run方法主要步骤如下,

1,打开socket,获取输入输出流,

socket = new LocalSocket();//创建socket对象
LocalSocketAddress address = determineSocketAddress();//获取socket地址,就是netd
socket.connect(address);//socket连接,和netd守护进程进行连接
InputStream inputStream = socket.getInputStream();//获取输入流
synchronized (mDaemonLock) {
    mOutputStream = socket.getOutputStream();//获取输出流
}
mCallbacks.onDaemonConnected();//回调NetdCallbackReceiver的onDaemonConnected方法

2,开启for循环读取netd守护进程发送上来的消息,当然消息也分为2类,

A,一类是NativeDaemonConnector发送请求, netd守护进程处理完之后的回答消息。这一类的消息直接放入mResponseQueue中。

B, netd守护进程直接上报的消息,这一类消息回调NetdCallbackReceiver的onEvent方法进行处理。

2.2 发送socket

NetworkManagementService一些方法需要netd守护进程处理,例如

createVirtualNetwork方法,

mConnector.execute("network", "create", netId, "vpn", hasDNS ? "1" : "0", secure ? "1" : "0");

removeNetwork方法

mConnector.execute("network", "destroy", netId);

addInterfaceToNetwork方法

modifyInterfaceInNetwork("add", "" + netId, iface);

removeInterfaceFromNetwork方法

modifyInterfaceInNetwork("remove", "" + netId, iface);

modifyInterfaceInNetwork方法如下,

mConnector.execute("network", "interface", action, netId, iface);

NativeDaemonEvent的execute发送包含命令的socket如下,

mOutputStream.write(rawCmd.getBytes(StandardCharsets.UTF_8));

这样,包含create/ destroy/ add/ remove等命令的字节就通过socket发送到netd进程了。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值