1. 程式人生 > >android 系統網路連線管理機制

android 系統網路連線管理機制

一  網路連線功能介紹

      ANDROID 系統網路連線和管理服務由四個系統服務C onnectivityService 、 NetworkPolicyManagerService 、 NetworkManagementService 、 NetworkStatsService 共同配合完成網路連線和管理功能,四個服務只有C onnectivityService 、 NetworkPolicyManagerService 兩個服務通過 NetworkPolicyManager 、 ConnectivityManager 兩個客戶端物件對應用程式提供對外 SDK 介面,而 NetworkManagementService

 、 NetworkStatsService 沒有對外提供 SDK 介面 , 但設定應用程式可以通過獲取系統服務介面使用 NetworkManagementService 、 NetworkStatsService 服務 .

     四個服務之間的關係類圖如下:

        

                                                     圖  網路連線系統類圖

        ConnectivityService 提供資料連線管理服務,N etworkPolicyManagerService 提供網路策略管理服務, NetworkStatsService

 提供網路傳輸資料統計服務, NetworkManagementService 提供對物理網路介面的管理服務, connectivityService 也包括 VPN 、 Tethering 物件提供虛擬連線及共享連線管理。

        ConnectivityService 、N etworkPolicyManagerService 、 NetworkStatsService 三個服務都通過 INetworkManagementService 介面跨程序訪問 NetworkManagementService服務,實現與網路介面的互動及資訊讀取。

        NetworkStatsService

 、 NetworkPolicyManagerService 兩個服務還通過 IConnectivityManager 介面與 connectivityService 服務通訊,從 connectivityService 讀取網路連線的資訊及開啟資料連線的策略控制。

        ConnectivityService 服務也通過 INetworkPolicyManager 介面呼叫 NetworkPolicyManagerService 的 API ,讀取網路限額資訊,登記監聽物件。 connectivityService 服務通過 NetworkPolicyManagerService 服務的 registerListener 函式向 NetworkPolicyManagerService 服務註冊一個 INetworkPolicyListener.Stub 監聽樁物件。 NetworkPolicyManagerService 通過該監聽物件的遠端代理介面向 ConnectivityService 服務傳送規則變化通知。

 另外C onnectivityService 服務的 Tethering 、 VPN 物件及 NetworkPolicyManagerService 、 NetworkStatsService 服務的內部 NetworkAlertObserver 型別的物件都直接或間接派生自 INetworkManagementEventObserver.Stub ,且四個物件都登記為 NetworkManagementService 的監聽物件, NetworkManagementService 服務通過 INetworkManagementEventObserver 介面向這些物件傳送網路介面事件通知。

       NetworkPolicyManagerService 維護網路使用策略,策略可以從一個策略檔案讀取(策略檔案儲存在系統目錄下的 netpolicy.xml 檔案中)。也可以通過 NetworkPolicyManager 對外提供的設定策略介面( setNetworkPolicies 及 setUidPolicy )進行設定, NetworkPolicyManagerService 能夠根據這些設定或從策略檔案中讀取的策略控制網路連線。另外 NetworkPolicyManagerService 還具有動態調節網路連線限額及動態設定網路連線的功能,動態調節網路連線限額機制是通過 INetworkStatsService 訪問 NetworkStatsService 服務獲得上面設定或讀取的策略匹配的網路連線型別的傳輸統計資訊( NetworkPolicyManagerService 採用 NetworkTemplate 進行網路連線型別的匹配),並根據這些資訊生成有效的規則,並提交給C onnectivityService 服務,並呼叫 NetworkManagementService 的 setInterfaceQuota 函式對網路連線的頻寬限額進行控制。

       動態設定網路連線規則的機制是 NetworkPolicyManagerService 服務通過檢測系統發出的一些相關事件(在 NetworkPolicyManagerService 的啟動 systemReady 函式中註冊),包括 ActivityManager 服務中 IProcessObserver 的 onForegroundActivitiesChanged 及 onProcessDied 回撥事件, NetworkManager 服務中 INetworkManagementEventObserver 的 limitReached 回撥事件,以及 ACTION_SCREEN_ON  、 CONNECTIVITY_ACTION_IMMEDIATE 、 ACTION_PACKAGE_ADDED 、 ACTION_UID_REMOVED 、 ACTION_NETWORK_STATS_UPDATED 、 ACTION_ALLOW_BACKGROUND 等 INTENT 事件,當這些事件發生時,根據事件不同對網路規則進行不同設定,如與應用程式相關的事件呼叫 updateRulesForUidLocked 函式對 uid 涉及的 NetworkRule 進行更新,其它事件通過 updateNetworkEnabledLocked 函式呼叫 connectivityService 的 setPolicyDataEnable 函式對特定網路連線型別的資料連線進行設定。

         NetworkStatsService 服務定期呼叫 performPoll 函式獲得網路傳輸統計資訊, performPoll 函式通過呼叫 NetworkManagementService 服務的 getNetworkStatsUidDetail 、getNetworkStatsSummary 及 getNetworkStatsTethering 函式從 /proc/ 目錄下的包含網路傳輸統計資料的檔案中讀取網路統計資訊,並轉換為 NetworkStatsHistory 資料結構,儲存到以網路介面名稱對應的 NetworkIdentitySet 型別和 UID 對應的 UidStatsKey型別的變數為 key 的 NetworkStatsService 的三個 HashMap 變數中。然後根據 performPoll 傳進來的引數標誌資訊(指示不同的 PERSIST 方法)呼叫 writeNetworkDevStatsLocked 、 writeNetworkXtStatsLocked 、 writeUidStatsLocked 函式把 HashMap 變數中的統計資訊分別寫入系統目錄下的三個相應的 BIN 檔案( netstats.bin 、 netstats_xt.bin 、 netstats_uid.bin )中。

        NetworkManagementService 的一個重要功能是與本地 netd 程序進行通訊,完成對網路物理介面的操作。 NetworkManagementService 通過 NativeDaemonConnector 與本地 netd 程序通過 LocalSocket 建立連線進行雙向通訊,傳送命令,讀取事件和命令應答訊息,對網路介面的實際操作由 netd 程序完成。 NativeDaemonConnector 物件是一個實現 Runnable 介面的物件, NativeDaemonConnector 物件在 NetworkManagementService 建立的執行緒中執行。

        NativeDaemonConnector 通過例項化時從 NetworkManagementService 傳進來的回撥函式向 NetworkManagementService 傳送從 netd 程序讀取的事件,主要事件有介面增加、介面移出、介面狀態變化、 LINK 狀態變化等介面改變事件以及頻寬控制事件。

二  connectivityService 連線實現機制

      整個類圖中C onnectivityService 服務是核心,實現對系統的所有資料連線進行管理,包括物理連線、虛擬連線以及共享連線。

       ConnectivityService 服務通過 NetworkStateTracker 類物件進行物理連線的管理、監控各種型別的網路連線,從中獲取網路資訊,C onnectivityService 服務通過 Tethering 物件提供網路連線共享服務,通過Vpn 物件提供 VPN 連線服務。

        ANDROID 4.0 版本準備支援的網路連線型別包括五個預設的同時只能啟用一個的資料連線型別: MOBILE _ TYPE 、 WIFI _ TYPE 、 BLUETOOTH _ TYPE 、 ETHERNET _ TYPE 、 WIMAX _ TYPE ( WIMAX _ TYPE 尚未實際實現)。另外還有八個可以和獨立的資料連線型別共存的子型別: MOBILE_MMS _ TYPE (用於多媒體訊息服務的移動資料連線型別,可以和 MOBILE_TYPE 資料連線型別相同也可以不同); MOBILE_SUPL_ TYPE(定位裝置的安全使用者平面定位服務用的移動資料連線型別,可以和 MOBILE_ TYPE 資料連線型別相同也可以不同); MOBILE_DUN_ TYPE (用於執行撥號網路橋接的移動資料連線型別,可以和 MOBILE_ TYPE 資料連線型別相同也可以不同); MOBILE_HIPRI_ TYPE (一個具有最高優先順序的移動資料連線型別,與 MOBILE _ TYPE 型別除了路由設定不同外,其它方面都相同。在路由設定時,如果預設路由存在,則僅當請求程序必須存取移動 DNS 服務及 IP 明確的通過 requestRouteToHost 函式請求時使用這個資料連線介面); MOBILE_FOTA_ TYPE (用於空中 韌體升級的移動資料連線 ); MOBILE_IMS_ TYPE (用於 IP 多媒體子系統的 移動資料連線型別); MOBILE_CBS_ TYPE (用於品牌服務的移動 資料連線型別),WIFI _P2P (用於 WIFI 點對點連線)。

      

 圖 2  NetworkStateTracker 類圖

         ConnectivityService 在例項化時讀取 frameworks\base\core\res\res\values 下的config.xml 資原始檔的 networkAttributes 屬性 ,並 networkAttributes 屬性的每個連線例項化一個 NetworkConfig 物件,然後根據 NetworkConfig 物件 為每個預設的資料連線型別採用單例模式例項化一個 具體 NetworkStateTracker 物件(每個具體 NetworkStateTracker 物件的派生關係如圖 2 所示)。

 每個具體的實際 NetworkStateTracker 物件都對應一個特定連線的服務,如 EthernetDataTracker 對應一個 EthernetService ,且每個具體的 NetworkStateTracker 物件通過對應服務的遠端管理物件與服務互動,讀取服務的資訊。如 EthernetDataTracker通過讀取 EthernetService 對應的資訊, MobileDataStateTracker通過 介面I Telephony 與 Telephony 服務互動, WifiStateTracker 通過 WifiManager 介面與 WifiService 服務互動。

       ConnectivityService 通過 NetworkStateTracker 物件實現對網路連線的控制和管理,每個連線都對應一個優先順序,當幾個預設型別的連線同時可用時, ConnectivityService 選擇最高優先順序的可用連線。 系統預設的網路優先順序定義在 frameworks\base\core\res\res\values 下的 config.xml 中的 networkAttributes 屬性中 。

    <string-array translatable="false" name="networkAttributes">

        <item>"ethernet,9,9,1,-1,true"</item>

        <item>"wifi,1,1,1,-1,true"</item>

        <item>"mobile,0,0,0,-1,true"</item>

        <item>"mobile_mms,2,0,2,60000,true"</item>

        <item>"mobile_supl,3,0,2,60000,true"</item>

        <item>"mobile_hipri,5,0,3,60000,true"</item>

        <item>"mobile_fota,10,0,2,60000,true"</item>

        <item>"mobile_ims,11,0,2,60000,true"</item>

        <item>"mobile_cbs,12,0,2,60000,true"</item>

        <item>"wifi_p2p,13,1,0,-1,true"</item>

    </string-array>

       ConnectivityService 服務也通過 NetworkStateTracker 獲得連線的狀態資訊及對網路狀態事件進行監控。 ConnectivityService 通過 NetworkStateTracker 物件的 startMonitoring 函式啟動資料連線的監控, ConnectivityService 服務的訊息處理控制代碼通過 startMonitoring 函式傳給 NetworkStateTracker 物件, NetworkStateTracker 物件通過該控制代碼向 ConnectivityService 傳送網路狀態事件。 

       ConnectivityService 通過 NetworkStateTracker 物件可以獲取的資料連線資訊主要包含三類: LinkProperties 描述一個網路連線屬性資訊(包含網路地址、閘道器、 DNS 、HTTP 代理等屬性資訊),一個網路連線可能由多個地址、多個閘道器、多個 DNS ,但僅有一個 HTTP 代理, LinkCapabilities (描述一個網路連線能力方面的資訊,包括頻寬、延遲等), NetworkInfo (描述一個給定型別的網路介面的狀態方面的資訊,包括網路連線狀態、網路型別、網路可連線性、是否漫遊等資訊)。 ConnectivityService 通過 NetworkStateTracker 物件的三個介面可以獲得這些資訊( getNetworkInfo , getLinkProperties 、 getLinkCapabilities ),並通過 getActiveNetworkInfo 、 getNetworkInfo 、getAllNetworkInfo 、 getLinkProperties 、 getAllNetworkState 等函式對外提供這方面的資訊。 ConnectivityService 服務呼叫 NetworkStateTracker 的 reconnect 、 teardown 、 setRadio 、 setUserDataEnable 、 setPolicyDataEnable 等函式實現對特定網路連線的控制。

       ConnectivityService 服務通過 Tethering 物件為 WIFI 、 BLUETOOTH 連線提供連線共享服務(其它裝置使用另一個裝置的連線,如 WIFI 熱點等), connectivityService 服務通過 tether 函式啟動網路介面的 Tethering 服務。可以通過藍芽、 WIFI 、 USB 對其它裝置提供 Tethering 服務。

 

                                                 圖 3  Tethering 類圖

        Tethering 物件使用了狀態模式來實現共享連線機制的實現,為每個狀態建立一個狀態物件,一個狀態物件根據不同情景可以切換到另一個狀態物件。 Tethering 類圖見圖 3 所示, Tethering 物件為每一個使用共享連線的物理介面維護一個 TetherInterfaceSM 型別的狀態機,管理 Tethering 介面的狀態。 TetherInterfaceSM 狀態機在 NetworkManagementService 服務觸發的 interfaceAdded 回撥中例項化。 TetherInterfaceSM 型別的狀態機包括 InitialState (初始狀態)、 StartingState (啟動狀態)、 TetheredState(共享狀態)、 UnavailableState (連線不可用狀態)四個狀態。 TetherInterfaceSM 通過 isAvailable 、 isTethered 、 isErrored 、 getLastError 等函式對外提供 Tethering 介面的狀態資訊,從而使 Tethering 的 getTetherableIfaces 、 getTetheredIfaces 、 getTetheredIfacePairs 、 getTetheringErroredIfaces 、 getLastTetherError 等函式可以從介面對應的狀態機中獲得 Tethering 介面的狀態。 TetherInterfaceSM 狀態機在正常共享工作情況下應該處於 TetheredState 狀態,在 TetheredState 狀態通過 NetworkManagementService的 tetherInterface 的函式來新增使用共享連線的介面。

        另外 Tethering 物件還提供了一個 TetherMasterSM 型別的主控狀態機,提供共享連線的啟動、停止等管理及連線狀態事件的監控並向 TetherInterfaceSM 狀態機發送事件通知。 TetherMasterSM 狀態機的狀態包括兩個大類: TetherMasterUtilState 及 ErrorState 。 TetherMasterUtilState 型別的狀態包括 InitialState (初始狀態)、 TetherModeAliveState (共享模式啟用狀態)兩個狀態。 ErrorState 型別的狀態包括 SetIpForwardingEnabledErrorState 、 SetIpForwardingEnabledErrorState 、 SetIpForwardingDisabledErrorState 、 StartTetheringErrorState 、 StopTetheringErrorState 、 SetDnsForwardersErrorState 等出錯狀態。正常共享工作情況下 TetherMasterSM 狀態機處於 TetherModeAliveState 狀態,在 TetherModeAliveState 狀態開啟共享連線,並呼叫 NetworkManagementService 服務的 setIpForwardingEnabled 、 setDnsForwarders 、 startTethering 函式啟動共享連線服務。

          Tethering 物件從 frameworks\base\core\res\res\values 下的 config.xml 的資原始檔中的 config_tether_upstream_types 屬性中讀取可用的共享連線型別, item 值為 1對應 WIFI 型別。

    <integer-array translatable="false" name="config_tether_upstream_types">

        <item>1</item>

    </integer-array>

         TetherInterfaceSM 狀態機由 Tethering 物件的 tether 函式啟動,並使 TetherInterfaceSM 和 TetherMasterSM 狀態機從初始狀態推進到正常共享狀態。

         TetherMasterSM 還採用觀察者模式向 TetherMasterSM 狀態機發送事件, TetherMasterSM 狀態機維護一個 TetherInterfaceSM 狀態機陣列列表, TetherMasterSM 狀態機通過該列表向列表中登記的每個 TetherInterfaceSM 狀態機發送 Tethering 介面狀態事件(包括錯誤狀態)。 TetherMasterSM 狀態機也可以直接向某個 TetherInterfaceSM 狀態機發送 Tethering 介面狀態事件。

         Tethering 介面的新增及共享連線的啟動、停止、 tether dns set 、 Ip Forward  Enabled 等功能由 NetworkManagementService 服務通過呼叫 NativeDaemonConnector 的 doCommand 函式向底層 netd  程序傳送命令完成,由 netd  程序實際完成以上工作。

         ConnectivityService 服務通過 prepareVpn 、 establishVpn 、、 protectVpn 三個函式並呼叫 VPN 物件的相應函式( prepare 、 establish 、 protect )建立 VPN 連線和維護 VPN 連線。 VPN 物件在 establish 函式中通過 JNI 呼叫建立 VPN 連線介面並設定 VPN連線地址和路由。