Merge pull request #155 from amnezia-vpn/feature/android_bandwidth_counter
Fix of bandwidth counter for Android
This commit is contained in:
commit
623c8ca6b0
11 changed files with 139 additions and 32 deletions
|
@ -31,6 +31,31 @@ class OpenVPNThreadv3(var service: VPNService): ClientAPI_OpenVPNClient(), Runna
|
|||
private var mAlreadyInitialised = false
|
||||
private var mService: VPNService = service
|
||||
|
||||
private var bytesInIndex = -1
|
||||
private var bytesOutIndex = -1
|
||||
|
||||
init {
|
||||
findConfigIndicies()
|
||||
}
|
||||
|
||||
private fun findConfigIndicies() {
|
||||
val n: Int = stats_n()
|
||||
|
||||
for (i in 0 until n) {
|
||||
val name: String = stats_name(i)
|
||||
if (name == "BYTES_IN") bytesInIndex = i
|
||||
if (name == "BYTES_OUT") bytesOutIndex = i
|
||||
}
|
||||
}
|
||||
|
||||
fun getTotalRxBytes(): Long {
|
||||
return stats_value(bytesInIndex)
|
||||
}
|
||||
|
||||
fun getTotalTxBytes(): Long {
|
||||
return stats_value(bytesOutIndex)
|
||||
}
|
||||
|
||||
override fun run() {
|
||||
|
||||
val config: ClientAPI_Config = ClientAPI_Config()
|
||||
|
|
|
@ -41,6 +41,7 @@ import java.io.Closeable
|
|||
import java.io.File
|
||||
import java.io.FileDescriptor
|
||||
import java.io.IOException
|
||||
import java.lang.Exception
|
||||
import android.net.VpnService as BaseVpnService
|
||||
|
||||
|
||||
|
@ -274,9 +275,16 @@ class VPNService : BaseVpnService(), LocalDnsService.Interface {
|
|||
return mConnectionTime
|
||||
}
|
||||
|
||||
var isUp: Boolean
|
||||
var isUp: Boolean = false
|
||||
get() {
|
||||
return currentTunnelHandle >= 0
|
||||
return when (mProtocol) {
|
||||
"openvpn" -> {
|
||||
field
|
||||
}
|
||||
else -> {
|
||||
currentTunnelHandle >= 0
|
||||
}
|
||||
}
|
||||
}
|
||||
set(value) {
|
||||
if (value) {
|
||||
|
@ -287,17 +295,52 @@ class VPNService : BaseVpnService(), LocalDnsService.Interface {
|
|||
mBinder.dispatchEvent(VPNServiceBinder.EVENTS.disconnected, "")
|
||||
mConnectionTime = 0
|
||||
}
|
||||
|
||||
val status: JSONObject
|
||||
get() {
|
||||
val deviceIpv4: String = ""
|
||||
|
||||
val status = when (mProtocol) {
|
||||
"openvpn" -> {
|
||||
if (mOpenVPNThreadv3 == null) {
|
||||
Status(null, null, null, null)
|
||||
} else {
|
||||
val rx = mOpenVPNThreadv3?.getTotalRxBytes() ?: ""
|
||||
val tx = mOpenVPNThreadv3?.getTotalTxBytes() ?: ""
|
||||
|
||||
Status(
|
||||
rx.toString(),
|
||||
tx.toString(),
|
||||
if (mConfig!!.has("server")) { mConfig?.getJSONObject("server")?.getString("ipv4Gateway") } else {""},
|
||||
if (mConfig!!.has("device")) { mConfig?.getJSONObject("device")?.getString("ipv4Address") } else {""}
|
||||
)
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
Status(
|
||||
getConfigValue("rx_bytes"),
|
||||
getConfigValue("tx_bytes"),
|
||||
if (mConfig!!.has("server")) { mConfig?.getJSONObject("server")?.getString("ipv4Gateway") } else {""},
|
||||
if (mConfig!!.has("server")) {mConfig?.getJSONObject("device")?.getString("ipv4Address") } else {""}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return JSONObject().apply {
|
||||
putOpt("rx_bytes", getConfigValue("rx_bytes"))
|
||||
putOpt("tx_bytes", getConfigValue("tx_bytes"))
|
||||
putOpt("endpoint", mConfig?.getJSONObject("server")?.getString("ipv4Gateway"))
|
||||
putOpt("deviceIpv4", mConfig?.getJSONObject("device")?.getString("ipv4Address"))
|
||||
putOpt("rx_bytes", status.rxBytes)
|
||||
putOpt("tx_bytes", status.txBytes)
|
||||
putOpt("endpoint", status.endpoint)
|
||||
putOpt("deviceIpv4", status.device)
|
||||
}
|
||||
}
|
||||
|
||||
data class Status(
|
||||
var rxBytes: String?,
|
||||
var txBytes: String?,
|
||||
var endpoint: String?,
|
||||
var device: String?
|
||||
)
|
||||
|
||||
/*
|
||||
* Checks if the VPN Permission is given.
|
||||
* If the permission is given, returns true
|
||||
|
@ -645,6 +688,7 @@ class VPNService : BaseVpnService(), LocalDnsService.Interface {
|
|||
|
||||
private fun startOpenVpn() {
|
||||
mOpenVPNThreadv3 = OpenVPNThreadv3(this)
|
||||
|
||||
Thread({
|
||||
mOpenVPNThreadv3?.run()
|
||||
}).start()
|
||||
|
|
|
@ -25,8 +25,10 @@ constexpr auto PERMISSIONHELPER_CLASS =
|
|||
"org/amnezia/vpn/qt/VPNPermissionHelper";
|
||||
} // namespace
|
||||
|
||||
AndroidController::AndroidController()
|
||||
AndroidController::AndroidController() : QObject()
|
||||
{
|
||||
connect(this, &AndroidController::scheduleStatusCheckSignal, this, &AndroidController::scheduleStatusCheckSlot);
|
||||
|
||||
s_instance = this;
|
||||
|
||||
auto activity = AndroidVPNActivity::instance();
|
||||
|
@ -50,8 +52,11 @@ AndroidController::AndroidController()
|
|||
|
||||
auto doc = QJsonDocument::fromJson(parcelBody.toUtf8());
|
||||
qlonglong time = doc.object()["time"].toVariant().toLongLong();
|
||||
|
||||
isConnected = doc.object()["connected"].toBool();
|
||||
|
||||
emit initialized(
|
||||
true, doc.object()["connected"].toBool(),
|
||||
true, isConnected,
|
||||
time > 0 ? QDateTime::fromMSecsSinceEpoch(time) : QDateTime());
|
||||
|
||||
setFallbackConnectedNotification();
|
||||
|
@ -61,27 +66,35 @@ AndroidController::AndroidController()
|
|||
[this](const QString& parcelBody) {
|
||||
Q_UNUSED(parcelBody);
|
||||
qDebug() << "Transact: connected";
|
||||
|
||||
isConnected = true;
|
||||
|
||||
emit scheduleStatusCheckSignal();
|
||||
|
||||
emit connectionStateChanged(VpnProtocol::Connected);
|
||||
}, Qt::QueuedConnection);
|
||||
|
||||
connect(activity, &AndroidVPNActivity::eventDisconnected, this,
|
||||
[this]() {
|
||||
qDebug() << "Transact: disconnected";
|
||||
|
||||
isConnected = false;
|
||||
|
||||
emit connectionStateChanged(VpnProtocol::Disconnected);
|
||||
}, Qt::QueuedConnection);
|
||||
|
||||
connect(activity, &AndroidVPNActivity::eventStatisticUpdate, this,
|
||||
[](const QString& parcelBody) {
|
||||
qDebug() << "Transact:: update";
|
||||
[this](const QString& parcelBody) {
|
||||
qDebug() << "Transact: update";
|
||||
|
||||
auto doc = QJsonDocument::fromJson(parcelBody.toUtf8());
|
||||
|
||||
// TODO: merge with "Android bandwidth" branch
|
||||
QString rx = doc.object()["rx_bytes"].toString();
|
||||
QString tx = doc.object()["tx_bytes"].toString();
|
||||
QString endpoint = doc.object()["endpoint"].toString();
|
||||
QString deviceIPv4 = doc.object()["deviceIpv4"].toString();
|
||||
|
||||
// emit statusUpdated(doc.object()["endpoint"].toString(),
|
||||
// doc.object()["deviceIpv4"].toString(),
|
||||
// doc.object()["tx_bytes"].toInt(),
|
||||
// doc.object()["rx_bytes"].toInt());
|
||||
emit statusUpdated(rx, tx, endpoint, deviceIPv4);
|
||||
}, Qt::QueuedConnection);
|
||||
|
||||
connect(activity, &AndroidVPNActivity::eventBackendLogs, this,
|
||||
|
@ -249,6 +262,16 @@ void AndroidController::setVpnConfig(const QJsonObject &newVpnConfig)
|
|||
m_vpnConfig = newVpnConfig;
|
||||
}
|
||||
|
||||
void AndroidController::scheduleStatusCheckSlot()
|
||||
{
|
||||
QTimer::singleShot(1000, [this]() {
|
||||
if (isConnected) {
|
||||
checkStatus();
|
||||
emit scheduleStatusCheckSignal();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const int ACTIVITY_RESULT_OK = 0xffffffff;
|
||||
/**
|
||||
* @brief Starts the Given intent in Context of the QTActivity
|
||||
|
|
|
@ -53,7 +53,11 @@ signals:
|
|||
void initialized(bool status, bool connected,
|
||||
const QDateTime& connectionDate);
|
||||
|
||||
void statusUpdated(QString totalRx, QString totalTx, QString endpoint, QString deviceIPv4);
|
||||
void scheduleStatusCheckSignal();
|
||||
|
||||
protected slots:
|
||||
void scheduleStatusCheckSlot();
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -69,6 +73,10 @@ private:
|
|||
std::function<void(const QString&)> m_logCallback;
|
||||
|
||||
static void startActivityForResult(JNIEnv* env, jobject /*thiz*/, jobject intent);
|
||||
|
||||
bool isConnected = false;
|
||||
|
||||
void scheduleStatusCheck();
|
||||
};
|
||||
|
||||
#endif // ANDROID_CONTROLLER_H
|
||||
|
|
|
@ -15,9 +15,7 @@
|
|||
AndroidVpnProtocol::AndroidVpnProtocol(Proto protocol, const QJsonObject &configuration, QObject* parent)
|
||||
: VpnProtocol(configuration, parent),
|
||||
m_protocol(protocol)
|
||||
{
|
||||
|
||||
}
|
||||
{ }
|
||||
|
||||
ErrorCode AndroidVpnProtocol::start()
|
||||
{
|
||||
|
@ -31,3 +29,11 @@ void AndroidVpnProtocol::stop()
|
|||
AndroidController::instance()->stop();
|
||||
}
|
||||
|
||||
void AndroidVpnProtocol::connectionDataUpdated(QString totalRx, QString totalTx, QString endpoint, QString deviceIPv4)
|
||||
{
|
||||
quint64 rxBytes = totalRx.toLongLong();
|
||||
quint64 txBytes = totalTx.toLongLong();
|
||||
|
||||
setBytesChanged(rxBytes, txBytes);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,9 @@ public:
|
|||
signals:
|
||||
|
||||
|
||||
public slots:
|
||||
void connectionDataUpdated(QString totalRx, QString totalTx, QString endpoint, QString deviceIPv4);
|
||||
|
||||
protected slots:
|
||||
|
||||
protected:
|
||||
|
|
|
@ -36,6 +36,7 @@ public:
|
|||
void cleanupBackendLogs();
|
||||
|
||||
signals:
|
||||
void newTransmitedDataCount(quint64 rxBytes, quint64 txBytes);
|
||||
|
||||
protected slots:
|
||||
|
||||
|
|
|
@ -25,8 +25,10 @@ Proto currentProto = amnezia::Proto::Any;
|
|||
}
|
||||
|
||||
IOSVpnProtocol::IOSVpnProtocol(Proto proto, const QJsonObject &configuration, QObject* parent)
|
||||
: VpnProtocol(configuration, parent),
|
||||
m_protocol(proto) {}
|
||||
: VpnProtocol(configuration, parent), m_protocol(proto)
|
||||
{
|
||||
connect(this, &IOSVpnProtocol::newTransmitedDataCount, this, &IOSVpnProtocol::setBytesChanged);
|
||||
}
|
||||
|
||||
IOSVpnProtocol* IOSVpnProtocol::instance() {
|
||||
return s_instance;
|
||||
|
@ -207,8 +209,7 @@ void IOSVpnProtocol::checkStatus()
|
|||
qDebug() << "ServerIpv4Gateway:" << QString::fromNSString(serverIpv4Gateway)
|
||||
<< "DeviceIpv4Address:" << QString::fromNSString(deviceIpv4Address)
|
||||
<< "RxBytes:" << rxBytes << "TxBytes:" << txBytes;
|
||||
emit bytesChanged(rxBytes, txBytes);
|
||||
|
||||
emit newTransmitedDataCount(rxBytes, txBytes);
|
||||
}];
|
||||
}
|
||||
|
||||
|
|
|
@ -67,7 +67,10 @@ VpnProtocol::VpnConnectionState VpnProtocol::connectionState() const
|
|||
|
||||
void VpnProtocol::setBytesChanged(quint64 receivedBytes, quint64 sentBytes)
|
||||
{
|
||||
emit bytesChanged(receivedBytes - m_receivedBytes, sentBytes - m_sentBytes);
|
||||
quint64 rxDiff = receivedBytes - m_receivedBytes;
|
||||
quint64 txDiff = sentBytes - m_sentBytes;
|
||||
|
||||
emit bytesChanged(rxDiff, txDiff);
|
||||
|
||||
m_receivedBytes = receivedBytes;
|
||||
m_sentBytes = sentBytes;
|
||||
|
|
|
@ -36,8 +36,6 @@ VpnConnection::VpnConnection(std::shared_ptr<Settings> settings,
|
|||
m_settings(settings),
|
||||
m_configurator(configurator),
|
||||
m_serverController(serverController),
|
||||
m_receivedBytes(0),
|
||||
m_sentBytes(0),
|
||||
m_isIOSConnected(false)
|
||||
{
|
||||
}
|
||||
|
@ -52,11 +50,7 @@ VpnConnection::~VpnConnection()
|
|||
|
||||
void VpnConnection::onBytesChanged(quint64 receivedBytes, quint64 sentBytes)
|
||||
{
|
||||
emit bytesChanged(receivedBytes - m_receivedBytes, sentBytes - m_sentBytes);
|
||||
|
||||
m_receivedBytes = receivedBytes;
|
||||
m_sentBytes = sentBytes;
|
||||
|
||||
emit bytesChanged(receivedBytes, sentBytes);
|
||||
}
|
||||
|
||||
void VpnConnection::onConnectionStateChanged(VpnProtocol::VpnConnectionState state)
|
||||
|
@ -362,6 +356,7 @@ void VpnConnection::connectToVpn(int serverIndex,
|
|||
Proto proto = ContainerProps::defaultProtocol(container);
|
||||
AndroidVpnProtocol *androidVpnProtocol = new AndroidVpnProtocol(proto, m_vpnConfiguration);
|
||||
connect(AndroidController::instance(), &AndroidController::connectionStateChanged, androidVpnProtocol, &AndroidVpnProtocol::setConnectionState);
|
||||
connect(AndroidController::instance(), &AndroidController::statusUpdated, androidVpnProtocol, &AndroidVpnProtocol::connectionDataUpdated);
|
||||
|
||||
m_vpnProtocol.reset(androidVpnProtocol);
|
||||
#elif defined Q_OS_IOS
|
||||
|
|
|
@ -93,8 +93,6 @@ private:
|
|||
QJsonObject m_vpnConfiguration;
|
||||
QJsonObject m_routeMode;
|
||||
QString m_remoteAddress;
|
||||
quint64 m_receivedBytes;
|
||||
quint64 m_sentBytes;
|
||||
bool m_isIOSConnected; //remove later move to isConnected,
|
||||
|
||||
#ifdef AMNEZIA_DESKTOP
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue