getConnectionOwnerUid

在這里插入圖片描述

在Android系統中,為了進行網絡權限控制、流量統計等,需要將網絡連接(如Socket)與發起該連接的應用UID關聯起來。這種關聯通常在內核中建立,并在用戶空間通過一些接口進行查詢。

1. 內核中的實現基礎

Linux內核中,每個Socket都有一個關聯的struct sock結構。在該結構中,有一個字段用于存儲用戶ID(UID):

struct sock {// ...kuid_t sk_uid; // 存儲創建該socket的進程的UID// ...
};

當應用創建一個Socket時,內核會將該進程的UID(即進程的有效UID)記錄在sock->sk_uid中。
該字段在 Socket 創建時由內核自動填充(通過 current_uid() 獲取當前進程 UID)。

2. 用戶空間查詢連接UID的方法

在用戶空間,Android系統提供了幾種方式來獲取網絡連接的UID:

(1) 使用/proc/net文件系統

Linux內核通過/proc/net下的文件(如/proc/net/tcp、/proc/net/udp等)暴露TCP和UDP連接的信息。這些文件中包含的每一行代表一個連接,其中有一列是UID(在Android中,該列是第7列,索引從0開始計數)。例如:

sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
0: 0100007F:1770 00000000:0000 0A 00000000:00000000 00:00000000 00000000 10086        0 123456

這里,UID為10086。

在Android系統中,系統服務(如NetworkStatsService)會解析這些文件以獲取每個連接的UID,從而進行流量統計。

(2) 使用Netlink Socket

更高效的方式是使用Netlink Socket(具體為NETLINK_INET_DIAG)來查詢Socket信息。Android系統使用NetlinkSocket類(位于frameworks/base/core/jni/android_net_Netlink.cpp)來發送查詢請求并解析響應。

在NetlinkSocket的請求中,可以指定查詢條件(如協議、狀態等),內核會返回匹配的Socket信息,其中就包括UID。

例如,在NetworkStatsService中,通過netlink方式收集Socket信息:

// 在Java層,通過調用Native方法
// frameworks/base/services/core/java/com/android/server/net/NetworkStatsService.java
private void readNetworkStatsDev() {// ...mNetworkDevStats = new NetworkStats(SystemClock.elapsedRealtime(), 6);mNetworkDevStats = NetworkStatsService.nativeReadNetworkDevStats();// ...
}

在Native層(frameworks/base/services/core/jni/com_android_server_net_NetworkStatsService.cpp)中,最終會調用netlink相關函數來獲取信息。

或通過 Netlink Socket 發送 inet_diag_req 請求,內核返回 inet_diag_msg 結構體,其中包含 idiag_uid 字段:

struct inet_diag_msg {__u8    idiag_family;__u8    idiag_state;// ...__u32   idiag_uid;    // 連接的 UID__u32   idiag_inode;  // Socket 的 inode
};

這是 NetworkStatsService 等系統服務內部使用的機制

(3) 系統API:TrafficStats.getUidRxBytes(int uid)等

Android提供了TrafficStats類,其中包含一些靜態方法,如:

getUidRxBytes(int uid)
getUidTxBytes(int uid)

這些方法允許應用獲取指定UID的流量統計。其內部實現也是通過讀取/proc/net文件或使用netlink,然后按UID聚合統計信息。

  • 系統 API(隱藏 API)
    Android 框架中部分類提供內部方法,如:
// 示例:通過 Socket 文件描述符獲取 UID
int uid = android.os.Process.getUidForSocket(int socketFd);

實際實現通過 JNI 調用到 libcore 中的 native 方法

(4) 系統服務中的連接跟蹤

在Android系統服務中,如ConnectivityService、NetworkStatsService等,會定期掃描網絡連接,并記錄每個連接的UID。這些信息可以用于防火墻規則(如根據UID阻止網絡訪問)或網絡統計。

3. 具體實現:getConnectionOwnerUid的類似功能

如果我們要實現一個getConnectionOwnerUid函數,其功能是給定一個本地地址和端口(或遠程地址和端口),返回該連接的UID,那么可以通過以下步驟:

查詢/proc/net文件:遍歷/proc/net/tcp和/proc/net/udp等文件,查找匹配本地地址和端口的行,然后提取UID列。
使用netlink查詢:構造一個inet_diag_req請求,設置查詢條件(如本地地址和端口),然后發送請求并解析響應,從響應中獲取UID。
4. 示例:通過/proc/net/tcp獲取UID
以下是一個簡化的示例,展示如何從/proc/net/tcp中獲取指定本地地址和端口的連接的UID:

public static int getConnectionOwnerUid(String protocol, String localAddr, int localPort) {String procFile = "/proc/net/" + protocol; // 如 "tcp" 或 "udp"try (BufferedReader reader = new BufferedReader(new FileReader(procFile))) {String line;// 跳過標題行reader.readLine();while ((line = reader.readLine()) != null) {// 按空格分割,注意可能有多個連續空格String[] tokens = line.trim().split("\\s+");if (tokens.length < 10) continue;// 本地地址和端口在第二個字段(索引1)String local = tokens[1];// 解析本地地址和端口String[] localParts = local.split(":");if (localParts.length != 2) continue;// 將16進制字符串形式的地址和端口轉換為可讀格式String addr = parseHexAddress(localParts[0]);int port = Integer.parseInt(localParts[1], 16);// 比較是否匹配if (addr.equals(localAddr) && port == localPort) {// UID在第8個字段(索引7)return Integer.parseInt(tokens[7]);}}} catch (IOException e) {e.printStackTrace();}return -1; // 未找到
}private static String parseHexAddress(String hex) {// 處理IPv4地址:4字節,小端序long addr = Long.parseLong(hex, 16);return String.format("%d.%d.%d.%d",(addr & 0xff),((addr >> 8) & 0xff),((addr >> 16) & 0xff),((addr >> 24) & 0xff));
}

注意:上述代碼僅為示例,實際應用中需要考慮IPv6、性能優化(避免頻繁讀取proc文件)以及權限問題(需要root權限才能讀取/proc/net文件)。

5. 權限要求

讀取/proc/net下的文件需要root權限,因為普通應用無法訪問這些文件。
使用netlink也需要root權限,因為創建NETLINK_INET_DIAG類型的socket需要CAP_NET_ADMIN能力。

6. 在Android系統中的應用

在Android系統內部,如NetworkStatsService、NetworkManagementService等系統服務中,會使用這些機制來跟蹤每個連接的UID,以便進行流量統計和網絡策略管理。

Android 版本差異

  • Android 7.0+ 強化了 UID 隔離,/proc/net 文件權限更嚴格。
  • Android 10+ 引入 CONNTRACK_UID 模塊替代部分舊機制。

總結

Android系統通過內核記錄每個Socket的創建者UID。
用戶空間可以通過讀取/proc/net下的文件或使用netlink機制來查詢活躍連接的UID。
這些查詢通常需要root權限,因此主要用于系統服務內部。
普通應用無法直接使用這些方法,但可以通過系統API(如TrafficStats)獲取按UID聚合的流量統計信息。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/93185.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/93185.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/93185.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

開源 Arkts 鴻蒙應用 開發(十)通訊--Http數據傳輸

文章的目的為了記錄使用Arkts 進行Harmony app 開發學習的經歷。本職為嵌入式軟件開發&#xff0c;公司安排開發app&#xff0c;臨時學習&#xff0c;完成app的開發。開發流程和要點有些記憶模糊&#xff0c;趕緊記錄&#xff0c;防止忘記。 相關鏈接&#xff1a; 開源 Arkts …

net8.0一鍵創建支持(RabbitMQ)

Necore項目生成器 - 在線創建Necore模板項目 | 一鍵下載 RabbitMQController.cs using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using RabbitMQ.Client; using RabbitMQ.Client.Events; using System.Text; using System.Threading.Tasks; using UnT.Tem…

Rust 泛型與特性

Rust 泛型與特性 引言 Rust 語言以其安全性和高效性在編程語言中獨樹一幟。Rust 的泛型和特性是其核心特性之一,它們使得開發者能夠編寫更加通用、靈活且安全的代碼。本文將深入探討 Rust 中的泛型和特性,包括其概念、用法以及在實際開發中的應用。 泛型簡介 概念 泛型是…

LangChain學習——結構化輸出和數據解析

LangChain 本指南全面介紹LangChain中結構化輸出生成和數據解析的核心功能&#xff0c;包括Pydantic BaseModel構造、各種輸出解析器的使用&#xff0c;以及高級錯誤處理機制。 詳細測試樣例和代碼可參考如下兩個鏈接&#xff1a; test_output_parserstest_pydantic_base_mo…

基于華為ENSP的BGP的狀態機深入淺出

本篇技術博文摘要 &#x1f31f; 本文章主要探討BGP狀態機如何控制BGP連接的建立與維護&#xff0c;以及BGP協議在運行過程中如何交換路由信息并確保網絡的穩定性 引言 &#x1f4d8; 在這個快速發展的技術時代&#xff0c;與時俱進是每個IT人的必修課。我是腎透側視攻城獅&…

Android 15中的16KB大頁有何優勢?

deepseek回答&#xff1a; Android 15引入的16KB大內存頁是系統性能優化的關鍵變革&#xff0c;其核心優勢體現在以下方面&#xff1a; ? 一、性能全面提升 系統整體加速 配置16KB頁面的設備整體性能提升5%-10%&#xff0c;通過減少內存管理開銷釋放更多資源用于應用運行。…

Gis數據的A*算法規劃航線

1.1 用到的技術棧geotools JTSJgrapht1.2 實現思路// 定義柵格網格參數private static final double CELL_SIZE_DEGREES 0.005;private static int gridWidth 0;//格子高度 index 1private static int gridHeight 0;//格子寬度// 1. 讀取GeoJSON文件File geoJsonFile new …

Spring Boot 默認使用 CGLIB,但CGLIB 無法代理 final 類或 final 方法

那么當這兩件事沖突時&#xff0c;Spring Boot 是怎么“解決”的呢&#xff1f;答案是&#xff1a;它不解決&#xff0c;也無法解決。當這種情況發生時&#xff0c;你的應用程序會直接啟動失敗。這不是 Spring Boot 的疏忽&#xff0c;而是由 CGLIB 的底層原理和 Java 語言的規…

cuda編程筆記(10)--memory access 優化

全局內存訪問優化&#xff08;Coalesced Access&#xff09; 什么是 Coalesced Access&#xff1f; 定義&#xff1a;一個 warp&#xff08;32 個線程&#xff09;在同一指令中訪問全局內存時&#xff0c;如果這些訪問請求可以合并成盡可能少的內存事務&#xff08;通常是 32…

閑庭信步使用圖像驗證平臺加速FPGA的開發:第三十一課——車牌識別的FPGA實現(3)車牌字符分割預處理

&#xff08;本系列只需要modelsim即可完成數字圖像的處理&#xff0c;每個工程都搭建了全自動化的仿真環境&#xff0c;只需要雙擊top_tb.bat文件就可以完成整個的仿真&#xff0c;大大降低了初學者的門檻&#xff01;&#xff01;&#xff01;&#xff01;如需要該系列的工程…

電子電氣架構 --- 汽車軟件全生命周期

我是穿拖鞋的漢子,魔都中堅持長期主義的汽車電子工程師。 老規矩,分享一段喜歡的文字,避免自己成為高知識低文化的工程師: 簡單,單純,喜歡獨處,獨來獨往,不易合同頻過著接地氣的生活,除了生存溫飽問題之外,沒有什么過多的欲望,表面看起來很高冷,內心熱情,如果你身…

力扣面試150(41/150)

7.25 56. 合并區間 以數組 intervals 表示若干個區間的集合&#xff0c;其中單個區間為 intervals[i] [starti, endi] 。請你合并所有重疊的區間&#xff0c;并返回 一個不重疊的區間數組&#xff0c;該數組需恰好覆蓋輸入中的所有區間 。 我的思路&#xff1a; 左端點升序…

【隧道篇 / IPsec】(7.6) ? 01. 利用向導快速建立IPsec安全隧道 (點對點) ? FortiGate 防火墻

【簡介】相信很多人已經習慣利用導向快速創建VPN了&#xff0c;而且已經有部分嘗鮮者已經用上了FortiOS 7.6&#xff0c;但是會發現FortiOS 7.6下的VPN向導改變了很多&#xff0c;一時無法下手&#xff0c;下面我們來看看最常見的點對點是如何配置的。環境介紹在配置IPsec VPN之…

PLLIP核

。1 號紅色框內的速度等級代表著設備的速度 等級&#xff0c;保存默認就好&#xff1b;2 號紅色框內設置輸入頻率&#xff1b;3 號紅色框選擇 PLL 的工作模式。我們 開發板用的晶振是 50MHz 的&#xff0c;故在 2 號紅色框內我們填寫 50MHz&#xff1b;我們在 3 號紅色框內選正…

1.1 Deep learning?pytorch ?深度學習訓練出來的模型通常有效但無法解釋合理性? 如何 解釋?

DL 是什么&#xff0c;你如何理解DL模型&#xff1f; DL 對于我而言&#xff0c;就是人類試圖想通過數學語言描述人類學習過程的一門技術&#xff0c;或者說學科。 因此 DL 模型 相當于 數學 的 一個 funciton &#xff0c;有輸入&#xff0c;通過function處理&#xff0c;得…

java實現在工具類中注入其他對象方式

方案1&#xff1a; Slf4j Component public class ChatdocApiClient {Value("${chatdoc.app-id}")private String appId;Value("${chatdoc.secret}")private String secret;Value("${chatdoc.domain}")private String domain;private final Rest…

electron中IPC 渲染進程與主進程通信方法解析

electron中ipcRenderer.invoke、ipcRenderer.on、ipcRenderer.send、ipcRenderer.sendSync作用與區別 IPC 渲染進程與主進程通信方法解析 ipcRenderer 的這幾個方法作用不完全相同&#xff0c;它們適用于不同的通信場景&#xff0c;核心區別在于通信方向、是否需要響應以及同步…

epoll_event 事件類型詳解

epoll_event 事件類型詳解 epoll_event 是 Linux epoll I/O 多路復用機制的核心結構體&#xff0c;其中的事件類型決定了 epoll 監控的行為和觸發條件。以下是各種事件類型的詳細解析&#xff1a; epoll_event 結構體 #include <sys/epoll.h>typedef union epoll_data {v…

設計自己的小傳輸協議 導論與概念

設計自己的小傳輸協議 導論與概念 1&#xff1a;聊一聊協議頭設計 ? 早在《TCP/IP詳解》中的第一句話中&#xff0c;我們就知道協議的含義是這樣的&#xff1a;協議是通信雙方共同遵守的一套規則&#xff0c;提供格式定義、語義解釋等&#xff0c;使不同設備或軟件能夠正確交…

iOS —— 天氣預報仿寫總結

在iOS中&#xff0c;最常見的網絡請求方式是NSURLSession&#xff0c;它是蘋果推薦的現代API&#xff0c;簡單安全且易于拓展。一次完整的網絡請求流程&#xff1a;構造 NSURL 對象創建 NSURLSessionDataTask發起請求&#xff08;resume&#xff09;在回調中解析數據回到主線程…