如果做网站推广,网站模板设计举例,上海最有名的公司集团,深圳排名优化哪家专业测试时关注到bw_costly_链 因为和iface有关。猜测这个链是动态生成的。 开关数据业务测试#xff0c;果然关闭数据业务后#xff0c;bw_OUTPUT中不再会调用bw_costly_rmnet_data3#xff0c;也没有bw_costly_rmnet_data3这个链了。 再次打开数据业务后出现了bw_costly_rmnet…测试时关注到bw_costly_链 因为和iface有关。猜测这个链是动态生成的。 开关数据业务测试果然关闭数据业务后bw_OUTPUT中不再会调用bw_costly_rmnet_data3也没有bw_costly_rmnet_data3这个链了。 再次打开数据业务后出现了bw_costly_rmnet_data2。说明上次上网的rmnet_data3口这此上网的rmnet_data2。
:/ # iptables -t filter -nvL bw_OUTPUT
Chain bw_OUTPUT (1 references)pkts bytes target prot opt in out source destination24 1909 bw_global_alert all -- * * 0.0.0.0/0 0.0.0.0/02 120 bw_costly_rmnet_data3 all -- * rmnet_data3 0.0.0.0/0 0.0.0.0/0是netd模块自己检测上网状态后自己添加的吗
查看代码是netd的BandwidthController生成。
int BandwidthController::setInterfaceQuota(const std::string iface, int64_t maxBytes) {const std::string cost iface;
..../* Insert ingress quota. */auto it mQuotaIfaces.find(iface);if (it ! mQuotaIfaces.end()) {if (int res updateQuota(cost, maxBytes)) {ALOGE(Failed update quota for %s, iface.c_str());removeInterfaceQuota(iface);return res;}it-second.quota maxBytes;return 0;}const std::string chain bw_costly_ iface;const int ruleInsertPos (mGlobalAlertBytes) ? 2 : 1;std::vectorstd::string cmds {*filter,StringPrintf(:%s -, chain.c_str()),StringPrintf(-A %s -j bw_penalty_box, chain.c_str()),StringPrintf(-I bw_INPUT %d -i %s -j %s, ruleInsertPos, iface.c_str(), chain.c_str()),StringPrintf(-I bw_OUTPUT %d -o %s -j %s, ruleInsertPos, iface.c_str(),chain.c_str()),StringPrintf(-A bw_FORWARD -i %s -j %s, iface.c_str(), chain.c_str()),StringPrintf(-A bw_FORWARD -o %s -j %s, iface.c_str(), chain.c_str()),StringPrintf(-A %s -m quota2 ! --quota % PRId64 --name %s -j REJECT, chain.c_str(),maxBytes, cost.c_str()),COMMIT\n,};if (iptablesRestoreFunction(V4V6, Join(cmds, \n), nullptr) ! 0) {ALOGE(Failed set quota rule);removeInterfaceQuota(iface);return -EREMOTEIO;}mQuotaIfaces[iface] QuotaInfo{maxBytes, 0};return 0;
}
netd 向上提供此接口内部除了ndc模块通过控制台可以调用没有自动关注网络状态调用setInterfaceQuota的地方
binder::Status NetdNativeService::bandwidthSetInterfaceQuota(const std::string ifName,int64_t bytes) {NETD_LOCKING_RPC(gCtls-bandwidthCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);int res gCtls-bandwidthCtrl.setInterfaceQuota(ifName, bytes);return statusFromErrcode(res);
}继续在android代码中搜索 framework的NetworkManagementService.java中调用 mNetdService.bandwidthSetInterfaceQuota public void setInterfaceQuota(String iface, long quotaBytes) {NetworkStack.checkNetworkStackPermission(mContext);synchronized (mQuotaLock) {if (mActiveQuotas.containsKey(iface)) {throw new IllegalStateException(iface iface already has quota);}try {// TODO: support quota shared across interfacesmNetdService.bandwidthSetInterfaceQuota(iface, quotaBytes);mActiveQuotas.put(iface, quotaBytes);} catch (RemoteException | ServiceSpecificException e) {throw new IllegalStateException(e);}synchronized (mTetheringStatsProviders) {for (ITetheringStatsProvider provider : mTetheringStatsProviders.keySet()) {try {provider.setInterfaceQuota(iface, quotaBytes);} catch (RemoteException e) {Log.e(TAG, Problem setting tethering data limit on provider mTetheringStatsProviders.get(provider) : e);}}}}}调用序列是 NatworkManagementService: NatworkManagementService.systemReady-prepareNativeDaemon()-setInterfaceQuota-mNetdService.bandwidthSetInterfaceQuota
下一步分析数据业务开关后是什么流程触发NatworkManagementService的setInterfaceQuota和removeInterfaceQuota的调用。
参考链接 Android系统中iptables的应用二BandwidthController https://blog.csdn.net/xiaokeweng/article/details/48810049