当前位置: 首页 > news >正文

Android bw_costly_<iface>链

测试时关注到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::vector<std::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

相关文章:

  • TypeScript算法每日一题:两数之和(1)
  • 计算机网络介绍
  • 09Linux GDB学习笔记
  • ctfshow jwt web入门
  • 【前端】vue+element项目中select下拉框label想要显示多个值多个字段
  • 自然语言处理(NLP)—— 神经网络语言处理
  • NPN与PNP的基础知识介绍
  • 使用git将本地文件上传到仓库+git常用指令
  • 二、Nginx目录结构与基本运行原理
  • SpringBoot:手动创建应用
  • 探索安全之道 | 企业漏洞管理:从理念到行动
  • 【ES001】elasticsearch实战经验总结(最近更新中)
  • Linux - 磁盘的分区和挂载
  • 操作系统基础知识
  • C语言面试题11至20题
  • css系列之关于字体的事
  • iOS小技巧之UIImagePickerController实现头像选择
  • JS题目及答案整理
  • Laravel 中的一个后期静态绑定
  • 安装python包到指定虚拟环境
  • 动手做个聊天室,前端工程师百无聊赖的人生
  • 记录:CentOS7.2配置LNMP环境记录
  • 前端学习笔记之原型——一张图说明`prototype`和`__proto__`的区别
  • 使用Envoy 作Sidecar Proxy的微服务模式-4.Prometheus的指标收集
  • 走向全栈之MongoDB的使用
  • 曾刷新两项世界纪录,腾讯优图人脸检测算法 DSFD 正式开源 ...
  • ###51单片机学习(1)-----单片机烧录软件的使用,以及如何建立一个工程项目
  • #Linux(Source Insight安装及工程建立)
  • #vue3 实现前端下载excel文件模板功能
  • #WEB前端(HTML属性)
  • #多叉树深度遍历_结合深度学习的视频编码方法--帧内预测
  • #周末课堂# 【Linux + JVM + Mysql高级性能优化班】(火热报名中~~~)
  • $HTTP_POST_VARS['']和$_POST['']的区别
  • (0)Nginx 功能特性
  • (1)(1.8) MSP(MultiWii 串行协议)(4.1 版)
  • (2)STM32单片机上位机
  • (C语言)求出1,2,5三个数不同个数组合为100的组合个数
  • (MonoGame从入门到放弃-1) MonoGame环境搭建
  • (Oracle)SQL优化技巧(一):分页查询
  • (Qt) 默认QtWidget应用包含什么?
  • (算法二)滑动窗口
  • ./和../以及/和~之间的区别
  • .gitignore
  • .NET 6 在已知拓扑路径的情况下使用 Dijkstra,A*算法搜索最短路径
  • .Net Remoting(分离服务程序实现) - Part.3
  • .NET 编写一个可以异步等待循环中任何一个部分的 Awaiter
  • .net 托管代码与非托管代码
  • .net/c# memcached 获取所有缓存键(keys)
  • .NET/C# 使用 ConditionalWeakTable 附加字段(CLR 版本的附加属性,也可用用来当作弱引用字典 WeakDictionary)
  • .Net转Java自学之路—SpringMVC框架篇六(异常处理)
  • []FET-430SIM508 研究日志 11.3.31
  • [【JSON2WEB】 13 基于REST2SQL 和 Amis 的 SQL 查询分析器
  • [23] 4K4D: Real-Time 4D View Synthesis at 4K Resolution
  • [AX]AX2012 AIF(四):文档服务应用实例
  • [BZOJ 3531][Sdoi2014]旅行(树链剖分+线段树)