summaryrefslogtreecommitdiffhomepage
path: root/tunnel/src/main/java/com/wireguard/android/backend/Statistics.java
blob: 322e766fc3ef8996839be93e787476a2a29f12ec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
 * Copyright © 2017-2021 WireGuard LLC. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0
 */

package com.wireguard.android.backend;

import android.os.SystemClock;
import android.util.Pair;

import com.wireguard.crypto.Key;
import com.wireguard.util.NonNullForAll;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * Class representing transfer statistics for a {@link Tunnel} instance.
 */
@NonNullForAll
public class Statistics {
    private static class Stat {
        long rx;
        long tx;
        LocalDateTime lastHandshake;

        Stat(long rx, long tx, LocalDateTime lastHandshake) {
            this.rx = rx;
            this.tx = tx;
            this.lastHandshake = lastHandshake;
        }
    }

    private final Map<Key, Stat> peerBytes = new HashMap<>();
    private long lastTouched = SystemClock.elapsedRealtime();

    Statistics() {
    }

    /**
     * Add a peer and its current data usage to the internal map.
     *
     * @param key A WireGuard public key bound to a particular peer
     * @param rx  The received traffic for the {@link com.wireguard.config.Peer} referenced by
     *            the provided {@link Key}. This value is in bytes
     * @param tx  The transmitted traffic for the {@link com.wireguard.config.Peer} referenced by
     *            the provided {@link Key}. This value is in bytes.
     */
    void add(final Key key, final long rx, final long tx, final LocalDateTime lastHandshake) {
        peerBytes.put(key, new Stat(rx, tx, lastHandshake));
        lastTouched = SystemClock.elapsedRealtime();
    }

    /**
     * Check if the statistics are stale, indicating the need for the {@link Backend} to update them.
     *
     * @return boolean indicating if the current statistics instance has stale values.
     */
    public boolean isStale() {
        return SystemClock.elapsedRealtime() - lastTouched > 900;
    }

    /**
     * Get the received traffic (in bytes) for the {@link com.wireguard.config.Peer} referenced by
     * the provided {@link Key}
     *
     * @param peer A {@link Key} representing a {@link com.wireguard.config.Peer}.
     * @return a long representing the number of bytes received by this peer.
     */
    public long peerRx(final Key peer) {
        final Stat stat = peerBytes.get(peer);
        if (stat == null)
            return 0;
        return stat.rx;
    }

    /**
     * Get the transmitted traffic (in bytes) for the {@link com.wireguard.config.Peer} referenced by
     * the provided {@link Key}
     *
     * @param peer A {@link Key} representing a {@link com.wireguard.config.Peer}.
     * @return a long representing the number of bytes transmitted by this peer.
     */
    public long peerTx(final Key peer) {
        final Stat stat = peerBytes.get(peer);
        if (stat == null)
            return 0;
        return stat.tx;
    }

    public LocalDateTime peerLastHandshake(final Key peer) {
        final Stat stat = peerBytes.get(peer);
        if (stat == null)
            return null;
        return stat.lastHandshake;
    }

    /**
     * Get the list of peers being tracked by this instance.
     *
     * @return An array of {@link Key} instances representing WireGuard
     * {@link com.wireguard.config.Peer}s
     */
    public Key[] peers() {
        return peerBytes.keySet().toArray(new Key[0]);
    }

    /**
     * Get the total received traffic by all the peers being tracked by this instance
     *
     * @return a long representing the number of bytes received by the peers being tracked.
     */
    public long totalRx() {
        long rx = 0;
        for (final Stat val : peerBytes.values()) {
            rx += val.rx;
        }
        return rx;
    }

    /**
     * Get the total transmitted traffic by all the peers being tracked by this instance
     *
     * @return a long representing the number of bytes transmitted by the peers being tracked.
     */
    public long totalTx() {
        long tx = 0;
        for (final Stat val : peerBytes.values()) {
            tx += val.tx;
        }
        return tx;
    }
}