• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
TetherStats(void)27         TetherStats(void)
28                 : rxBytes(-1), rxPackets(-1),
29                     txBytes(-1), txPackets(-1) {};
TetherStats(std::string ifnIn,std::string ifnOut,int64_t rxB,int64_t rxP,int64_t txB,int64_t txP)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     static const char* LOCAL_INPUT;
84     static const char* LOCAL_FORWARD;
85     static const char* LOCAL_OUTPUT;
86     static const char* LOCAL_RAW_PREROUTING;
87     static const char* LOCAL_MANGLE_POSTROUTING;
88 
89 protected:
90     class QuotaInfo {
91     public:
QuotaInfo(std::string ifn,int64_t q,int64_t a)92       QuotaInfo(std::string ifn, int64_t q, int64_t a)
93               : ifaceName(ifn), quota(q), alert(a) {};
94         std::string ifaceName;
95         int64_t quota;
96         int64_t alert;
97     };
98 
99     enum IptIpVer { IptIpV4, IptIpV6 };
100     enum IptOp { IptOpInsert, IptOpReplace, IptOpDelete };
101     enum IptRejectOp { IptRejectAdd, IptRejectNoAdd };
102     enum NaughtyAppOp { NaughtyAppOpAdd, NaughtyAppOpRemove };
103     enum QuotaType { QuotaUnique, QuotaShared };
104     enum RunCmdErrHandling { RunCmdFailureBad, RunCmdFailureOk };
105 #if LOG_NDEBUG
106     enum IptFailureLog { IptFailShow, IptFailHide };
107 #else
108     enum IptFailureLog { IptFailShow, IptFailHide = IptFailShow };
109 #endif
110     int maninpulateNaughtyApps(int numUids, char *appStrUids[], NaughtyAppOp appOp);
111 
112     int prepCostlyIface(const char *ifn, QuotaType quotaType);
113     int cleanupCostlyIface(const char *ifn, QuotaType quotaType);
114 
115     std::string makeIptablesNaughtyCmd(IptOp op, int uid);
116     std::string makeIptablesQuotaCmd(IptOp op, const char *costName, int64_t quota);
117 
118     int runIptablesAlertCmd(IptOp op, const char *alertName, int64_t bytes);
119     int runIptablesAlertFwdCmd(IptOp op, const char *alertName, int64_t bytes);
120 
121     /* Runs for both ipv4 and ipv6 iptables */
122     int runCommands(int numCommands, const char *commands[], RunCmdErrHandling cmdErrHandling);
123     /* Runs for both ipv4 and ipv6 iptables, appends -j REJECT --reject-with ...  */
124     static int runIpxtablesCmd(const char *cmd, IptRejectOp rejectHandling,
125                                IptFailureLog failureHandling = IptFailShow);
126     static int runIptablesCmd(const char *cmd, IptRejectOp rejectHandling, IptIpVer iptIpVer,
127                               IptFailureLog failureHandling = IptFailShow);
128 
129 
130     // Provides strncpy() + check overflow.
131     static int StrncpyAndCheck(char *buffer, const char *src, size_t buffSize);
132 
133     int updateQuota(const char *alertName, int64_t bytes);
134 
135     int setCostlyAlert(const char *costName, int64_t bytes, int64_t *alertBytes);
136     int removeCostlyAlert(const char *costName, int64_t *alertBytes);
137 
138     /*
139      * stats should have ifaceIn and ifaceOut initialized.
140      * fp should be a file to the FORWARD rules of iptables.
141      * extraProcessingInfo: contains raw parsed data, and error info.
142      */
143     static int parseForwardChainStats(TetherStats &stats, FILE *fp,
144                                       std::string &extraProcessingInfo);
145 
146     /*------------------*/
147 
148     std::list<std::string> sharedQuotaIfaces;
149     int64_t sharedQuotaBytes;
150     int64_t sharedAlertBytes;
151     int64_t globalAlertBytes;
152     /*
153      * This tracks the number of tethers setup.
154      * The FORWARD chain is updated in the following cases:
155      *  - The 1st time a globalAlert is setup and there are tethers setup.
156      *  - Anytime a globalAlert is removed and there are tethers setup.
157      *  - The 1st tether is setup and there is a globalAlert active.
158      *  - The last tether is removed and there is a globalAlert active.
159      */
160     int globalAlertTetherCount;
161 
162     std::list<QuotaInfo> quotaIfaces;
163     std::list<int /*appUid*/> naughtyAppUids;
164 
165 private:
166     static const char *IPT_FLUSH_COMMANDS[];
167     static const char *IPT_CLEANUP_COMMANDS[];
168     static const char *IPT_SETUP_COMMANDS[];
169     static const char *IPT_BASIC_ACCOUNTING_COMMANDS[];
170 
171     /* Alphabetical */
172     static const int  ALERT_RULE_POS_IN_COSTLY_CHAIN;
173     static const char ALERT_GLOBAL_NAME[];
174     static const int  MAX_CMD_ARGS;
175     static const int  MAX_CMD_LEN;
176     static const int  MAX_IFACENAME_LEN;
177     static const int  MAX_IPT_OUTPUT_LINE_LEN;
178 
179     /*
180      * When false, it will directly use system() instead of logwrap()
181      */
182     static bool useLogwrapCall;
183 };
184 
185 #endif
186