Home | History | Annotate | Download | only in netd
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 #ifndef _BANDWIDTH_CONTROLLER_H
     17 #define _BANDWIDTH_CONTROLLER_H
     18 
     19 #include <list>
     20 #include <string>
     21 #include <utility>  // for pair
     22 
     23 class BandwidthController {
     24 public:
     25     class TetherStats {
     26     public:
     27         TetherStats(void)
     28                 : rxBytes(-1), rxPackets(-1),
     29                     txBytes(-1), txPackets(-1) {};
     30         TetherStats(std::string ifnIn, std::string ifnOut,
     31                 int64_t rxB, int64_t rxP,
     32                 int64_t txB, int64_t txP)
     33                         : ifaceIn(ifnIn), ifaceOut(ifnOut),
     34                             rxBytes(rxB), rxPackets(rxP),
     35                     txBytes(txB), txPackets(txP) {};
     36         std::string ifaceIn;
     37         std::string ifaceOut;
     38         int64_t rxBytes, rxPackets;
     39         int64_t txBytes, txPackets;
     40         /*
     41          * Allocates a new string representing this:
     42          * ifaceIn ifaceOut rx_bytes rx_packets tx_bytes tx_packets
     43          * The caller is responsible for free()'ing the returned ptr.
     44          */
     45         char *getStatsLine(void);
     46     };
     47 
     48     BandwidthController();
     49     int enableBandwidthControl(void);
     50     int disableBandwidthControl(void);
     51 
     52     int setInterfaceSharedQuota(const char *iface, int64_t bytes);
     53     int getInterfaceSharedQuota(int64_t *bytes);
     54     int removeInterfaceSharedQuota(const char *iface);
     55 
     56     int setInterfaceQuota(const char *iface, int64_t bytes);
     57     int getInterfaceQuota(const char *iface, int64_t *bytes);
     58     int removeInterfaceQuota(const char *iface);
     59 
     60     int addNaughtyApps(int numUids, char *appUids[]);
     61     int removeNaughtyApps(int numUids, char *appUids[]);
     62 
     63     int setGlobalAlert(int64_t bytes);
     64     int removeGlobalAlert(void);
     65     int setGlobalAlertInForwardChain(void);
     66     int removeGlobalAlertInForwardChain(void);
     67 
     68     int setSharedAlert(int64_t bytes);
     69     int removeSharedAlert(void);
     70 
     71     int setInterfaceAlert(const char *iface, int64_t bytes);
     72     int removeInterfaceAlert(const char *iface);
     73 
     74     /*
     75      * stats should have ifaceIn and ifaceOut initialized.
     76      * Byte counts should be left to the default (-1).
     77      */
     78     int getTetherStats(TetherStats &stats);
     79 
     80 protected:
     81     class QuotaInfo {
     82     public:
     83       QuotaInfo(std::string ifn, int64_t q, int64_t a)
     84               : ifaceName(ifn), quota(q), alert(a) {};
     85         std::string ifaceName;
     86         int64_t quota;
     87         int64_t alert;
     88     };
     89 
     90     enum IptIpVer { IptIpV4, IptIpV6 };
     91     enum IptOp { IptOpInsert, IptOpReplace, IptOpDelete };
     92     enum IptRejectOp { IptRejectAdd, IptRejectNoAdd };
     93     enum NaughtyAppOp { NaughtyAppOpAdd, NaughtyAppOpRemove };
     94     enum QuotaType { QuotaUnique, QuotaShared };
     95     enum RunCmdErrHandling { RunCmdFailureBad, RunCmdFailureOk };
     96 
     97     int maninpulateNaughtyApps(int numUids, char *appStrUids[], NaughtyAppOp appOp);
     98 
     99     int prepCostlyIface(const char *ifn, QuotaType quotaType);
    100     int cleanupCostlyIface(const char *ifn, QuotaType quotaType);
    101 
    102     std::string makeIptablesNaughtyCmd(IptOp op, int uid);
    103     std::string makeIptablesQuotaCmd(IptOp op, const char *costName, int64_t quota);
    104 
    105     int runIptablesAlertCmd(IptOp op, const char *alertName, int64_t bytes);
    106     int runIptablesAlertFwdCmd(IptOp op, const char *alertName, int64_t bytes);
    107 
    108     /* Runs for both ipv4 and ipv6 iptables */
    109     int runCommands(int numCommands, const char *commands[], RunCmdErrHandling cmdErrHandling);
    110     /* Runs for both ipv4 and ipv6 iptables, appends -j REJECT --reject-with ...  */
    111     static int runIpxtablesCmd(const char *cmd, IptRejectOp rejectHandling);
    112     static int runIptablesCmd(const char *cmd, IptRejectOp rejectHandling, IptIpVer iptIpVer);
    113 
    114     // Provides strncpy() + check overflow.
    115     static int StrncpyAndCheck(char *buffer, const char *src, size_t buffSize);
    116 
    117     int updateQuota(const char *alertName, int64_t bytes);
    118 
    119     int setCostlyAlert(const char *costName, int64_t bytes, int64_t *alertBytes);
    120     int removeCostlyAlert(const char *costName, int64_t *alertBytes);
    121 
    122     /*
    123      * stats should have ifaceIn and ifaceOut initialized.
    124      * fp should be a file to the FORWARD rules of iptables.
    125      */
    126     static int parseForwardChainStats(TetherStats &stats, FILE *fp);
    127 
    128     /*------------------*/
    129 
    130     std::list<std::string> sharedQuotaIfaces;
    131     int64_t sharedQuotaBytes;
    132     int64_t sharedAlertBytes;
    133     int64_t globalAlertBytes;
    134     /*
    135      * This tracks the number of tethers setup.
    136      * The FORWARD chain is updated in the following cases:
    137      *  - The 1st time a globalAlert is setup and there are tethers setup.
    138      *  - Anytime a globalAlert is removed and there are tethers setup.
    139      *  - The 1st tether is setup and there is a globalAlert active.
    140      *  - The last tether is removed and there is a globalAlert active.
    141      */
    142     int globalAlertTetherCount;
    143 
    144     std::list<QuotaInfo> quotaIfaces;
    145     std::list<int /*appUid*/> naughtyAppUids;
    146 
    147 private:
    148     static const char *IPT_CLEANUP_COMMANDS[];
    149     static const char *IPT_SETUP_COMMANDS[];
    150     static const char *IPT_BASIC_ACCOUNTING_COMMANDS[];
    151 
    152     /* Alphabetical */
    153     static const char ALERT_IPT_TEMPLATE[];
    154     static const int  ALERT_RULE_POS_IN_COSTLY_CHAIN;
    155     static const char ALERT_GLOBAL_NAME[];
    156     static const char IP6TABLES_PATH[];
    157     static const char IPTABLES_PATH[];
    158     static const int  MAX_CMD_ARGS;
    159     static const int  MAX_CMD_LEN;
    160     static const int  MAX_IFACENAME_LEN;
    161     static const int  MAX_IPT_OUTPUT_LINE_LEN;
    162 
    163     /*
    164      * When false, it will directly use system() instead of logwrap()
    165      */
    166     static bool useLogwrapCall;
    167 };
    168 
    169 #endif
    170