14a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall/*
24a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall * Copyright (C) 2011 The Android Open Source Project
34a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall *
44a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall * Licensed under the Apache License, Version 2.0 (the "License");
54a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall * you may not use this file except in compliance with the License.
64a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall * You may obtain a copy of the License at
74a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall *
84a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall *      http://www.apache.org/licenses/LICENSE-2.0
94a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall *
104a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall * Unless required by applicable law or agreed to in writing, software
114a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall * distributed under the License is distributed on an "AS IS" BASIS,
124a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall * See the License for the specific language governing permissions and
144a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall * limitations under the License.
154a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall */
164a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall#ifndef _BANDWIDTH_CONTROLLER_H
174a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall#define _BANDWIDTH_CONTROLLER_H
184a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall
194a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall#include <list>
204a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall#include <string>
21fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall#include <utility>  // for pair
22db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
234a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrallclass BandwidthController {
244a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrallpublic:
25db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    class TetherStats {
26db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    public:
27db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        TetherStats(void)
28db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall                : rxBytes(-1), rxPackets(-1),
29db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall                    txBytes(-1), txPackets(-1) {};
30db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        TetherStats(std::string ifnIn, std::string ifnOut,
31db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall                int64_t rxB, int64_t rxP,
32db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall                int64_t txB, int64_t txP)
33db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall                        : ifaceIn(ifnIn), ifaceOut(ifnOut),
34db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall                            rxBytes(rxB), rxPackets(rxP),
35db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall                    txBytes(txB), txPackets(txP) {};
36db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        std::string ifaceIn;
37db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        std::string ifaceOut;
38db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        int64_t rxBytes, rxPackets;
39db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        int64_t txBytes, txPackets;
40db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        /*
41db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall         * Allocates a new string representing this:
42db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall         * ifaceIn ifaceOut rx_bytes rx_packets tx_bytes tx_packets
43db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall         * The caller is responsible for free()'ing the returned ptr.
44db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall         */
45db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall        char *getStatsLine(void);
46db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    };
47db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
48fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall    BandwidthController();
490031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall
500031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall    int setupIptablesHooks(void);
510031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall
520031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall    int enableBandwidthControl(bool force);
53fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall    int disableBandwidthControl(void);
54fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall
550dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall    int setInterfaceSharedQuota(const char *iface, int64_t bytes);
568a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    int getInterfaceSharedQuota(int64_t *bytes);
57fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall    int removeInterfaceSharedQuota(const char *iface);
58fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall
590dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall    int setInterfaceQuota(const char *iface, int64_t bytes);
608a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    int getInterfaceQuota(const char *iface, int64_t *bytes);
610dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall    int removeInterfaceQuota(const char *iface);
620dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall
63fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall    int addNaughtyApps(int numUids, char *appUids[]);
64fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall    int removeNaughtyApps(int numUids, char *appUids[]);
654a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall
668a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    int setGlobalAlert(int64_t bytes);
678a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    int removeGlobalAlert(void);
68c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall    int setGlobalAlertInForwardChain(void);
69c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall    int removeGlobalAlertInForwardChain(void);
708a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall
718a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    int setSharedAlert(int64_t bytes);
728a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    int removeSharedAlert(void);
738a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall
748a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    int setInterfaceAlert(const char *iface, int64_t bytes);
758a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    int removeInterfaceAlert(const char *iface);
760dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall
77db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    /*
78db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall     * stats should have ifaceIn and ifaceOut initialized.
79db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall     * Byte counts should be left to the default (-1).
80db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall     */
81a2a64f004f1677daf16b0b03d589d6572ec547c2JP Abgrall    int getTetherStats(TetherStats &stats, std::string &extraProcessingInfo);
82db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
838e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey    static const char* LOCAL_INPUT;
848e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey    static const char* LOCAL_FORWARD;
858e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey    static const char* LOCAL_OUTPUT;
868e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey    static const char* LOCAL_RAW_PREROUTING;
878e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey    static const char* LOCAL_MANGLE_POSTROUTING;
888e188ed5c989ddcc07f0f5e9839493c22d17e7b6Jeff Sharkey
894a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrallprotected:
908a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    class QuotaInfo {
918a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    public:
928a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall      QuotaInfo(std::string ifn, int64_t q, int64_t a)
938a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall              : ifaceName(ifn), quota(q), alert(a) {};
948a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        std::string ifaceName;
958a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        int64_t quota;
968a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        int64_t alert;
978a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    };
98db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
9926e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall    enum IptIpVer { IptIpV4, IptIpV6 };
10026e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall    enum IptOp { IptOpInsert, IptOpReplace, IptOpDelete };
10126e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall    enum IptRejectOp { IptRejectAdd, IptRejectNoAdd };
10226e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall    enum NaughtyAppOp { NaughtyAppOpAdd, NaughtyAppOpRemove };
10326e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall    enum QuotaType { QuotaUnique, QuotaShared };
10426e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall    enum RunCmdErrHandling { RunCmdFailureBad, RunCmdFailureOk };
1051fb02dfc26e06b83e756ab3538b7ebc2136f535dJP Abgrall#if LOG_NDEBUG
1061fb02dfc26e06b83e756ab3538b7ebc2136f535dJP Abgrall    enum IptFailureLog { IptFailShow, IptFailHide };
1071fb02dfc26e06b83e756ab3538b7ebc2136f535dJP Abgrall#else
1081fb02dfc26e06b83e756ab3538b7ebc2136f535dJP Abgrall    enum IptFailureLog { IptFailShow, IptFailHide = IptFailShow };
1091fb02dfc26e06b83e756ab3538b7ebc2136f535dJP Abgrall#endif
11026e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall    int maninpulateNaughtyApps(int numUids, char *appStrUids[], NaughtyAppOp appOp);
1114a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall
11226e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall    int prepCostlyIface(const char *ifn, QuotaType quotaType);
11326e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall    int cleanupCostlyIface(const char *ifn, QuotaType quotaType);
1140dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall
1150dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall    std::string makeIptablesNaughtyCmd(IptOp op, int uid);
11626e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall    std::string makeIptablesQuotaCmd(IptOp op, const char *costName, int64_t quota);
1170dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall
1188a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    int runIptablesAlertCmd(IptOp op, const char *alertName, int64_t bytes);
119c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall    int runIptablesAlertFwdCmd(IptOp op, const char *alertName, int64_t bytes);
1208a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall
1210dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall    /* Runs for both ipv4 and ipv6 iptables */
12226e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall    int runCommands(int numCommands, const char *commands[], RunCmdErrHandling cmdErrHandling);
1230dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall    /* Runs for both ipv4 and ipv6 iptables, appends -j REJECT --reject-with ...  */
1241fb02dfc26e06b83e756ab3538b7ebc2136f535dJP Abgrall    static int runIpxtablesCmd(const char *cmd, IptRejectOp rejectHandling,
1251fb02dfc26e06b83e756ab3538b7ebc2136f535dJP Abgrall                               IptFailureLog failureHandling = IptFailShow);
1261fb02dfc26e06b83e756ab3538b7ebc2136f535dJP Abgrall    static int runIptablesCmd(const char *cmd, IptRejectOp rejectHandling, IptIpVer iptIpVer,
1271fb02dfc26e06b83e756ab3538b7ebc2136f535dJP Abgrall                              IptFailureLog failureHandling = IptFailShow);
1281fb02dfc26e06b83e756ab3538b7ebc2136f535dJP Abgrall
12926e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall
13026e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall    // Provides strncpy() + check overflow.
13126e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall    static int StrncpyAndCheck(char *buffer, const char *src, size_t buffSize);
1320dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall
1338a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    int updateQuota(const char *alertName, int64_t bytes);
1348a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall
1358a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    int setCostlyAlert(const char *costName, int64_t bytes, int64_t *alertBytes);
1368a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    int removeCostlyAlert(const char *costName, int64_t *alertBytes);
1378a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall
13811b4e9b26fe7b878992162afb39f5a8acfd143edJP Abgrall    /*
139db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall     * stats should have ifaceIn and ifaceOut initialized.
140db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall     * fp should be a file to the FORWARD rules of iptables.
141a2a64f004f1677daf16b0b03d589d6572ec547c2JP Abgrall     * extraProcessingInfo: contains raw parsed data, and error info.
14211b4e9b26fe7b878992162afb39f5a8acfd143edJP Abgrall     */
143a2a64f004f1677daf16b0b03d589d6572ec547c2JP Abgrall    static int parseForwardChainStats(TetherStats &stats, FILE *fp,
1440031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall                                      std::string &extraProcessingInfo);
145db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
146db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    /*------------------*/
147db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
148db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    std::list<std::string> sharedQuotaIfaces;
149db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    int64_t sharedQuotaBytes;
150db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    int64_t sharedAlertBytes;
151db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    int64_t globalAlertBytes;
152c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall    /*
153c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall     * This tracks the number of tethers setup.
154c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall     * The FORWARD chain is updated in the following cases:
155c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall     *  - The 1st time a globalAlert is setup and there are tethers setup.
156c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall     *  - Anytime a globalAlert is removed and there are tethers setup.
157c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall     *  - The 1st tether is setup and there is a globalAlert active.
158c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall     *  - The last tether is removed and there is a globalAlert active.
159c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall     */
160c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall    int globalAlertTetherCount;
161c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall
162db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    std::list<QuotaInfo> quotaIfaces;
163db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    std::list<int /*appUid*/> naughtyAppUids;
1648a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall
1654a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrallprivate:
1660031cead820149e2fe3ccb3cc2fe05758a3cb5c2JP Abgrall    static const char *IPT_FLUSH_COMMANDS[];
167db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    static const char *IPT_CLEANUP_COMMANDS[];
168db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    static const char *IPT_SETUP_COMMANDS[];
169db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    static const char *IPT_BASIC_ACCOUNTING_COMMANDS[];
170db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
171db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    /* Alphabetical */
172db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    static const int  ALERT_RULE_POS_IN_COSTLY_CHAIN;
173c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall    static const char ALERT_GLOBAL_NAME[];
174db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    static const int  MAX_CMD_ARGS;
175db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    static const int  MAX_CMD_LEN;
176db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    static const int  MAX_IFACENAME_LEN;
177db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    static const int  MAX_IPT_OUTPUT_LINE_LEN;
178db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
179db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    /*
180db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall     * When false, it will directly use system() instead of logwrap()
181db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall     */
182db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    static bool useLogwrapCall;
1834a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall};
1844a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall
1854a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall#endif
186