BandwidthController.h revision a2a64f004f1677daf16b0b03d589d6572ec547c2
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();
49fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall    int enableBandwidthControl(void);
50fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall    int disableBandwidthControl(void);
51fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall
520dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall    int setInterfaceSharedQuota(const char *iface, int64_t bytes);
538a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    int getInterfaceSharedQuota(int64_t *bytes);
54fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall    int removeInterfaceSharedQuota(const char *iface);
55fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall
560dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall    int setInterfaceQuota(const char *iface, int64_t bytes);
578a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    int getInterfaceQuota(const char *iface, int64_t *bytes);
580dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall    int removeInterfaceQuota(const char *iface);
590dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall
60fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall    int addNaughtyApps(int numUids, char *appUids[]);
61fa6f46d3370ae5475fc3bc8273bbe04ee7348d60JP Abgrall    int removeNaughtyApps(int numUids, char *appUids[]);
624a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall
638a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    int setGlobalAlert(int64_t bytes);
648a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    int removeGlobalAlert(void);
65c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall    int setGlobalAlertInForwardChain(void);
66c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall    int removeGlobalAlertInForwardChain(void);
678a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall
688a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    int setSharedAlert(int64_t bytes);
698a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    int removeSharedAlert(void);
708a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall
718a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    int setInterfaceAlert(const char *iface, int64_t bytes);
728a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    int removeInterfaceAlert(const char *iface);
730dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall
74db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    /*
75db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall     * stats should have ifaceIn and ifaceOut initialized.
76db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall     * Byte counts should be left to the default (-1).
77db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall     */
78a2a64f004f1677daf16b0b03d589d6572ec547c2JP Abgrall    int getTetherStats(TetherStats &stats, std::string &extraProcessingInfo);
79db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
804a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrallprotected:
818a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    class QuotaInfo {
828a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    public:
838a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall      QuotaInfo(std::string ifn, int64_t q, int64_t a)
848a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall              : ifaceName(ifn), quota(q), alert(a) {};
858a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        std::string ifaceName;
868a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        int64_t quota;
878a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall        int64_t alert;
888a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    };
89db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
9026e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall    enum IptIpVer { IptIpV4, IptIpV6 };
9126e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall    enum IptOp { IptOpInsert, IptOpReplace, IptOpDelete };
9226e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall    enum IptRejectOp { IptRejectAdd, IptRejectNoAdd };
9326e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall    enum NaughtyAppOp { NaughtyAppOpAdd, NaughtyAppOpRemove };
9426e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall    enum QuotaType { QuotaUnique, QuotaShared };
9526e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall    enum RunCmdErrHandling { RunCmdFailureBad, RunCmdFailureOk };
960dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall
9726e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall    int maninpulateNaughtyApps(int numUids, char *appStrUids[], NaughtyAppOp appOp);
984a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall
9926e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall    int prepCostlyIface(const char *ifn, QuotaType quotaType);
10026e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall    int cleanupCostlyIface(const char *ifn, QuotaType quotaType);
1010dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall
1020dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall    std::string makeIptablesNaughtyCmd(IptOp op, int uid);
10326e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall    std::string makeIptablesQuotaCmd(IptOp op, const char *costName, int64_t quota);
1040dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall
1058a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    int runIptablesAlertCmd(IptOp op, const char *alertName, int64_t bytes);
106c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall    int runIptablesAlertFwdCmd(IptOp op, const char *alertName, int64_t bytes);
1078a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall
1080dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall    /* Runs for both ipv4 and ipv6 iptables */
10926e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall    int runCommands(int numCommands, const char *commands[], RunCmdErrHandling cmdErrHandling);
1100dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall    /* Runs for both ipv4 and ipv6 iptables, appends -j REJECT --reject-with ...  */
11126e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall    static int runIpxtablesCmd(const char *cmd, IptRejectOp rejectHandling);
11226e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall    static int runIptablesCmd(const char *cmd, IptRejectOp rejectHandling, IptIpVer iptIpVer);
11326e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall
11426e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall    // Provides strncpy() + check overflow.
11526e0d49fa743d7881104196a9eda733bd2aac92fJP Abgrall    static int StrncpyAndCheck(char *buffer, const char *src, size_t buffSize);
1160dad7c2f1f6994fbe5e85b9e1fc72d29d6453211JP Abgrall
1178a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    int updateQuota(const char *alertName, int64_t bytes);
1188a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall
1198a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    int setCostlyAlert(const char *costName, int64_t bytes, int64_t *alertBytes);
1208a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    int removeCostlyAlert(const char *costName, int64_t *alertBytes);
1218a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall
12211b4e9b26fe7b878992162afb39f5a8acfd143edJP Abgrall    /*
123db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall     * stats should have ifaceIn and ifaceOut initialized.
124db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall     * fp should be a file to the FORWARD rules of iptables.
125a2a64f004f1677daf16b0b03d589d6572ec547c2JP Abgrall     * extraProcessingInfo: contains raw parsed data, and error info.
12611b4e9b26fe7b878992162afb39f5a8acfd143edJP Abgrall     */
127a2a64f004f1677daf16b0b03d589d6572ec547c2JP Abgrall    static int parseForwardChainStats(TetherStats &stats, FILE *fp,
128a2a64f004f1677daf16b0b03d589d6572ec547c2JP Abgrall				      std::string &extraProcessingInfo);
129db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
130db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    /*------------------*/
131db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
132db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    std::list<std::string> sharedQuotaIfaces;
133db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    int64_t sharedQuotaBytes;
134db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    int64_t sharedAlertBytes;
135db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    int64_t globalAlertBytes;
136c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall    /*
137c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall     * This tracks the number of tethers setup.
138c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall     * The FORWARD chain is updated in the following cases:
139c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall     *  - The 1st time a globalAlert is setup and there are tethers setup.
140c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall     *  - Anytime a globalAlert is removed and there are tethers setup.
141c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall     *  - The 1st tether is setup and there is a globalAlert active.
142c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall     *  - The last tether is removed and there is a globalAlert active.
143c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall     */
144c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall    int globalAlertTetherCount;
145c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall
146db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    std::list<QuotaInfo> quotaIfaces;
147db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    std::list<int /*appUid*/> naughtyAppUids;
1488a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall
1494a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrallprivate:
150db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    static const char *IPT_CLEANUP_COMMANDS[];
151db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    static const char *IPT_SETUP_COMMANDS[];
152db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    static const char *IPT_BASIC_ACCOUNTING_COMMANDS[];
153db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
154db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    /* Alphabetical */
1558a93272255f1b7e3083a97e1e28ddf675c0c7fb0JP Abgrall    static const char ALERT_IPT_TEMPLATE[];
156db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    static const int  ALERT_RULE_POS_IN_COSTLY_CHAIN;
157c6c673496184bed6d62cf92a6fc7ed43fd94acd5JP Abgrall    static const char ALERT_GLOBAL_NAME[];
158db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    static const char IP6TABLES_PATH[];
159db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    static const char IPTABLES_PATH[];
160db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    static const int  MAX_CMD_ARGS;
161db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    static const int  MAX_CMD_LEN;
162db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    static const int  MAX_IFACENAME_LEN;
163db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    static const int  MAX_IPT_OUTPUT_LINE_LEN;
164db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall
165db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    /*
166db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall     * When false, it will directly use system() instead of logwrap()
167db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall     */
168db7da58e8d2aa021060098057f944ef754be06e3JP Abgrall    static bool useLogwrapCall;
1694a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall};
1704a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall
1714a5f5ca3c9e07fc3e6feca2afde07f41a8a64f11JP Abgrall#endif
172