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 
     50     int setupIptablesHooks(void);
     51 
     52     int enableBandwidthControl(bool force);
     53     int disableBandwidthControl(void);
     54 
     55     int setInterfaceSharedQuota(const char *iface, int64_t bytes);
     56     int getInterfaceSharedQuota(int64_t *bytes);
     57     int removeInterfaceSharedQuota(const char *iface);
     58 
     59     int setInterfaceQuota(const char *iface, int64_t bytes);
     60     int getInterfaceQuota(const char *iface, int64_t *bytes);
     61     int removeInterfaceQuota(const char *iface);
     62 
     63     int addNaughtyApps(int numUids, char *appUids[]);
     64     int removeNaughtyApps(int numUids, char *appUids[]);
     65 
     66     int setGlobalAlert(int64_t bytes);
     67     int removeGlobalAlert(void);
     68     int setGlobalAlertInForwardChain(void);
     69     int removeGlobalAlertInForwardChain(void);
     70 
     71     int setSharedAlert(int64_t bytes);
     72     int removeSharedAlert(void);
     73 
     74     int setInterfaceAlert(const char *iface, int64_t bytes);
     75     int removeInterfaceAlert(const char *iface);
     76 
     77     /*
     78      * stats should have ifaceIn and ifaceOut initialized.
     79      * Byte counts should be left to the default (-1).
     80      */
     81     int getTetherStats(TetherStats &stats, std::string &extraProcessingInfo);
     82 
     83 protected:
     84     class QuotaInfo {
     85     public:
     86       QuotaInfo(std::string ifn, int64_t q, int64_t a)
     87               : ifaceName(ifn), quota(q), alert(a) {};
     88         std::string ifaceName;
     89         int64_t quota;
     90         int64_t alert;
     91     };
     92 
     93     enum IptIpVer { IptIpV4, IptIpV6 };
     94     enum IptOp { IptOpInsert, IptOpReplace, IptOpDelete };
     95     enum IptRejectOp { IptRejectAdd, IptRejectNoAdd };
     96     enum NaughtyAppOp { NaughtyAppOpAdd, NaughtyAppOpRemove };
     97     enum QuotaType { QuotaUnique, QuotaShared };
     98     enum RunCmdErrHandling { RunCmdFailureBad, RunCmdFailureOk };
     99 #if LOG_NDEBUG
    100     enum IptFailureLog { IptFailShow, IptFailHide };
    101 #else
    102     enum IptFailureLog { IptFailShow, IptFailHide = IptFailShow };
    103 #endif
    104     int maninpulateNaughtyApps(int numUids, char *appStrUids[], NaughtyAppOp appOp);
    105 
    106     int prepCostlyIface(const char *ifn, QuotaType quotaType);
    107     int cleanupCostlyIface(const char *ifn, QuotaType quotaType);
    108 
    109     std::string makeIptablesNaughtyCmd(IptOp op, int uid);
    110     std::string makeIptablesQuotaCmd(IptOp op, const char *costName, int64_t quota);
    111 
    112     int runIptablesAlertCmd(IptOp op, const char *alertName, int64_t bytes);
    113     int runIptablesAlertFwdCmd(IptOp op, const char *alertName, int64_t bytes);
    114 
    115     /* Runs for both ipv4 and ipv6 iptables */
    116     int runCommands(int numCommands, const char *commands[], RunCmdErrHandling cmdErrHandling);
    117     /* Runs for both ipv4 and ipv6 iptables, appends -j REJECT --reject-with ...  */
    118     static int runIpxtablesCmd(const char *cmd, IptRejectOp rejectHandling,
    119                                IptFailureLog failureHandling = IptFailShow);
    120     static int runIptablesCmd(const char *cmd, IptRejectOp rejectHandling, IptIpVer iptIpVer,
    121                               IptFailureLog failureHandling = IptFailShow);
    122 
    123 
    124     // Provides strncpy() + check overflow.
    125     static int StrncpyAndCheck(char *buffer, const char *src, size_t buffSize);
    126 
    127     int updateQuota(const char *alertName, int64_t bytes);
    128 
    129     int setCostlyAlert(const char *costName, int64_t bytes, int64_t *alertBytes);
    130     int removeCostlyAlert(const char *costName, int64_t *alertBytes);
    131 
    132     /*
    133      * stats should have ifaceIn and ifaceOut initialized.
    134      * fp should be a file to the FORWARD rules of iptables.
    135      * extraProcessingInfo: contains raw parsed data, and error info.
    136      */
    137     static int parseForwardChainStats(TetherStats &stats, FILE *fp,
    138                                       std::string &extraProcessingInfo);
    139 
    140     /*------------------*/
    141 
    142     std::list<std::string> sharedQuotaIfaces;
    143     int64_t sharedQuotaBytes;
    144     int64_t sharedAlertBytes;
    145     int64_t globalAlertBytes;
    146     /*
    147      * This tracks the number of tethers setup.
    148      * The FORWARD chain is updated in the following cases:
    149      *  - The 1st time a globalAlert is setup and there are tethers setup.
    150      *  - Anytime a globalAlert is removed and there are tethers setup.
    151      *  - The 1st tether is setup and there is a globalAlert active.
    152      *  - The last tether is removed and there is a globalAlert active.
    153      */
    154     int globalAlertTetherCount;
    155 
    156     std::list<QuotaInfo> quotaIfaces;
    157     std::list<int /*appUid*/> naughtyAppUids;
    158 
    159 private:
    160     static const char *IPT_FLUSH_COMMANDS[];
    161     static const char *IPT_CLEANUP_COMMANDS[];
    162     static const char *IPT_SETUP_COMMANDS[];
    163     static const char *IPT_BASIC_ACCOUNTING_COMMANDS[];
    164 
    165     /* Alphabetical */
    166     static const int  ALERT_RULE_POS_IN_COSTLY_CHAIN;
    167     static const char ALERT_GLOBAL_NAME[];
    168     static const int  MAX_CMD_ARGS;
    169     static const int  MAX_CMD_LEN;
    170     static const int  MAX_IFACENAME_LEN;
    171     static const int  MAX_IPT_OUTPUT_LINE_LEN;
    172 
    173     /*
    174      * When false, it will directly use system() instead of logwrap()
    175      */
    176     static bool useLogwrapCall;
    177 };
    178 
    179 #endif
    180