diff options
Diffstat (limited to 'ui/src/main/java/com')
3 files changed, 126 insertions, 16 deletions
diff --git a/ui/src/main/java/com/wireguard/android/fragment/TunnelDetailFragment.kt b/ui/src/main/java/com/wireguard/android/fragment/TunnelDetailFragment.kt index ed49d56d..50d43690 100644 --- a/ui/src/main/java/com/wireguard/android/fragment/TunnelDetailFragment.kt +++ b/ui/src/main/java/com/wireguard/android/fragment/TunnelDetailFragment.kt @@ -112,7 +112,7 @@ class TunnelDetailFragment : BaseFragment() { for (i in 0 until binding.peersLayout.childCount) { val peer: TunnelDetailPeerBinding = DataBindingUtil.getBinding(binding.peersLayout.getChildAt(i)) ?: continue - val publicKey = peer.item!!.peer.publicKey + val publicKey = peer.item!!.publicKey val rx = statistics.peerRx(publicKey) val tx = statistics.peerTx(publicKey) if (rx == 0L && tx == 0L) { diff --git a/ui/src/main/java/com/wireguard/android/model/ObservableTunnel.kt b/ui/src/main/java/com/wireguard/android/model/ObservableTunnel.kt index ef22f846..9684ffab 100644 --- a/ui/src/main/java/com/wireguard/android/model/ObservableTunnel.kt +++ b/ui/src/main/java/com/wireguard/android/model/ObservableTunnel.kt @@ -7,6 +7,7 @@ package com.wireguard.android.model import android.util.Log import androidx.databinding.BaseObservable import androidx.databinding.Bindable +import com.wireguard.android.Application import com.wireguard.android.BR import com.wireguard.android.backend.Dhcp import com.wireguard.android.backend.Statistics @@ -14,10 +15,12 @@ import com.wireguard.android.backend.Tunnel import com.wireguard.android.databinding.Keyed import com.wireguard.android.util.applicationScope import com.wireguard.android.viewmodel.ConfigDetail +import com.wireguard.android.viewmodel.PeerDetail import com.wireguard.config.Config import com.wireguard.config.InetEndpoint -import com.wireguard.crypto.Key; -import java.util.Optional; +import com.wireguard.config.InetNetwork +import com.wireguard.crypto.Key +import java.util.Optional import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -63,10 +66,12 @@ class ObservableTunnel internal constructor( if (state != Tunnel.State.UP) { onStatisticsChanged(null) onDhcpChanged(null) - onEndpointChange(null, null) + Application.getCoroutineScope().launch { + onPeersReset() + } } else { configDetail?.peers?.forEach { - var endpoint: InetEndpoint? = it.peer.endpoint.orElse(null) + var endpoint: InetEndpoint? = it.peer?.endpoint?.orElse(null) it.endpoint = Optional.ofNullable(endpoint?.getResolved()?.get()) } } @@ -118,8 +123,8 @@ class ObservableTunnel internal constructor( } fun onConfigChanged(config: Config?): ConfigDetail? { - this.config = config this.configDetail = ConfigDetail(config) + this.config = config notifyPropertyChanged(BR.config) return configDetail } @@ -171,18 +176,89 @@ class ObservableTunnel internal constructor( return dhcp } - override fun onEndpointChange(publicKey: Key?, newEndpoint: InetEndpoint?) { + // Remove dynamic peers, and reset static peers + fun onPeersReset() { + Log.i(TAG, "ObservableTunnel onPeersReset") + var toRemove: MutableList<PeerDetail> = ArrayList() + + configDetail?.peers?.forEach { + if (it.peer == null) { + toRemove.add(it) + } else { + it.endpoint = Optional.empty() + } + } + + toRemove.forEach { + Log.i(TAG, "ObservableTunnel remove " + it) + configDetail?.peers?.remove(it) + } + } + + override fun onEndpointChange(publicKey: Key, newEndpoint: InetEndpoint?) { + Application.getCoroutineScope().launch { + onEndpointChanged(publicKey, newEndpoint) + } + } + + private fun onEndpointChanged(publicKey: Key, newEndpoint: InetEndpoint?) { + Log.i(TAG, "ObservableTunnel onEndpointChange " + newEndpoint) + var peer: PeerDetail? = null + configDetail?.peers?.forEach { - Log.i(TAG, "ObservableTunnel peer " + it + ", " + it.peer) - if (publicKey == null || it.peer.publicKey.equals(publicKey)) { - if (newEndpoint == null) { - it.endpoint = it.peer.endpoint - } else { - it.endpoint = newEndpoint.getResolved() - } + if (it.publicKey.equals(publicKey) == true) { + Log.i(TAG, "ObservableTunnel peer " + it + ", " + it.peer) + peer = it; + } + } + + if (peer == null) { + Log.i(TAG, "ObservableTunnel create peer " + publicKey) + peer = PeerDetail(publicKey) + configDetail?.peers?.add(peer) + } + + var peer2: PeerDetail = peer!! + + if (newEndpoint != null) { + peer2.endpoint = newEndpoint.getResolved() + } else { + var peer3 = peer2.peer + peer2.endpoint = if (peer3 != null) peer3.endpoint else Optional.empty() + } + } + + fun lookupPeer(publicKey: Key): PeerDetail { + configDetail?.peers?.forEach { + if (it.publicKey.equals(publicKey) == true) { + Log.i(TAG, "ObservableTunnel peer " + it + ", " + it.peer) + return it } } + + Log.i(TAG, "ObservableTunnel create peer " + publicKey) + var peer: PeerDetail = PeerDetail(publicKey) + configDetail?.peers?.add(peer) + + return peer + } + + override fun onAllowedIpsChange(publicKey: Key, addNetworks: List<InetNetwork>?, removeNetworks: List<InetNetwork>?) { + Application.getCoroutineScope().launch { + onAllowedIpsChanged(publicKey, addNetworks, removeNetworks) + } + } + + private fun onAllowedIpsChanged(publicKey: Key, addNetworks: List<InetNetwork>?, removeNetworks: List<InetNetwork>?) { + var peer: PeerDetail = lookupPeer(publicKey) + + removeNetworks?.let() { + peer.allowedIps.removeAll(removeNetworks) + } + addNetworks?.let() { + peer.allowedIps.addAll(addNetworks) + } } diff --git a/ui/src/main/java/com/wireguard/android/viewmodel/PeerDetail.kt b/ui/src/main/java/com/wireguard/android/viewmodel/PeerDetail.kt index abc81998..80b32fd5 100644 --- a/ui/src/main/java/com/wireguard/android/viewmodel/PeerDetail.kt +++ b/ui/src/main/java/com/wireguard/android/viewmodel/PeerDetail.kt @@ -4,25 +4,37 @@ import android.util.Log import androidx.databinding.BaseObservable import androidx.databinding.Bindable import androidx.databinding.Observable +import androidx.databinding.ObservableList +import androidx.databinding.ObservableArrayList import com.wireguard.android.BR import com.wireguard.config.InetEndpoint +import com.wireguard.config.InetNetwork import com.wireguard.config.Peer +import com.wireguard.crypto.Key; import java.util.Optional; +import kotlin.collections.LinkedHashSet + class PeerDetail : BaseObservable { - var peer: Peer + var peer: Peer? private var owner: ConfigDetail? = null @get:Bindable + var publicKey: Key + + @get:Bindable + var allowedIps: ObservableList<InetNetwork> = ObservableArrayList<InetNetwork>() + + @get:Bindable var endpoint: Optional<InetEndpoint> = Optional.empty() get() { if (!field.isEmpty()) { return field } else { - return peer.endpoint + return Optional.ofNullable(peer?.endpoint?.get()) } } @@ -32,8 +44,20 @@ class PeerDetail : BaseObservable { notifyPropertyChanged(BR.endpoint) } + @get:Bindable + var persistentKeepalive: Optional<Int> = Optional.empty() + constructor(other: Peer) { peer = other + publicKey = other.getPublicKey() + allowedIps.addAll(other.getAllowedIps()) + endpoint = other.getEndpoint(); + persistentKeepalive = other.getPersistentKeepalive() + } + + constructor(publicKey: Key) { + peer = null + this.publicKey = publicKey } fun bind(owner: ConfigDetail) { @@ -45,6 +69,16 @@ class PeerDetail : BaseObservable { super.addOnPropertyChangedCallback(callback) } + /** + * Converts the {@code Peer} into a string suitable for debugging purposes. The {@code Peer} is + * identified by its public key and (if known) its endpoint. + * + * @return a concise single-line identifier for the {@code Peer} + */ + override fun toString(): String { + return "(Peer " + publicKey.toBase64() + ")" + } + companion object { private const val TAG = "WireGuard/PeerDetail" } |