diff --git a/android/src/main/java/com/tailscale/ipn/ui/localapi/Client.kt b/android/src/main/java/com/tailscale/ipn/ui/localapi/Client.kt index 8800e7d..fa7b221 100644 --- a/android/src/main/java/com/tailscale/ipn/ui/localapi/Client.kt +++ b/android/src/main/java/com/tailscale/ipn/ui/localapi/Client.kt @@ -8,7 +8,6 @@ import com.tailscale.ipn.ui.model.BugReportID import com.tailscale.ipn.ui.model.Errors import com.tailscale.ipn.ui.model.Ipn import com.tailscale.ipn.ui.model.IpnLocal -import com.tailscale.ipn.ui.model.IpnState import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -44,7 +43,6 @@ private object Endpoint { const val TAILFS_SERVER_ADDRESS = "tailfs/fileserver-address" } -typealias StatusResponseHandler = (Result) -> Unit typealias BugReportIdHandler = (Result) -> Unit typealias PrefsHandler = (Result) -> Unit @@ -53,10 +51,6 @@ typealias PrefsHandler = (Result) -> Unit * corresponding method on this Client. */ class Client(private val scope: CoroutineScope) { - fun status(responseHandler: StatusResponseHandler) { - get(Endpoint.STATUS, responseHandler = responseHandler) - } - fun bugReportId(responseHandler: BugReportIdHandler) { post(Endpoint.BUG_REPORT, responseHandler = responseHandler) } diff --git a/android/src/main/java/com/tailscale/ipn/ui/model/Dns.kt b/android/src/main/java/com/tailscale/ipn/ui/model/Dns.kt deleted file mode 100644 index a655ab8..0000000 --- a/android/src/main/java/com/tailscale/ipn/ui/model/Dns.kt +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package com.tailscale.ipn.ui.model - -import kotlinx.serialization.Serializable - -class Dns { - @Serializable - data class HostEntry(val addr: Addr?, val hosts: List?) - - @Serializable - data class OSConfig( - val hosts: List? = null, - val nameservers: List? = null, - val searchDomains: List? = null, - val matchDomains: List? = null, - ) { - val isEmpty: Boolean - get() = (hosts.isNullOrEmpty()) && - (nameservers.isNullOrEmpty()) && - (searchDomains.isNullOrEmpty()) && - (matchDomains.isNullOrEmpty()) - } -} - -class DnsType { - @Serializable - data class Resolver(var Addr: String? = null, var BootstrapResolution: List? = null) -} diff --git a/android/src/main/java/com/tailscale/ipn/ui/model/Ipn.kt b/android/src/main/java/com/tailscale/ipn/ui/model/Ipn.kt index ab723cd..5a84dcd 100644 --- a/android/src/main/java/com/tailscale/ipn/ui/model/Ipn.kt +++ b/android/src/main/java/com/tailscale/ipn/ui/model/Ipn.kt @@ -9,13 +9,9 @@ class Ipn { // Represents the overall state of the Tailscale engine. enum class State(val value: Int) { - NoState(0), - InUseOtherUser(1), - NeedsLogin(2), - NeedsMachineAuth(3), - Stopped(4), - Starting(5), - Running(6); + NoState(0), InUseOtherUser(1), NeedsLogin(2), NeedsMachineAuth(3), Stopped(4), Starting(5), Running( + 6 + ); companion object { fun fromInt(value: Int): State { @@ -28,20 +24,20 @@ class Ipn { // on which NotifyWatchOpts were set when the Notifier was created. @Serializable data class Notify( - val Version: String? = null, - val ErrMessage: String? = null, - val LoginFinished: Empty.Message? = null, - val FilesWaiting: Empty.Message? = null, - val State: Int? = null, - var Prefs: Prefs? = null, - var NetMap: Netmap.NetworkMap? = null, - var Engine: EngineStatus? = null, - var BrowseToURL: String? = null, - var BackendLogId: String? = null, - var LocalTCPPort: Int? = null, - var IncomingFiles: List? = null, - var ClientVersion: Tailcfg.ClientVersion? = null, - var TailFSShares: Map? = null, + val Version: String? = null, + val ErrMessage: String? = null, + val LoginFinished: Empty.Message? = null, + val FilesWaiting: Empty.Message? = null, + val State: Int? = null, + var Prefs: Prefs? = null, + var NetMap: NetworkMap? = null, + var Engine: EngineStatus? = null, + var BrowseToURL: String? = null, + var BackendLogId: String? = null, + var LocalTCPPort: Int? = null, + var IncomingFiles: List? = null, +// var ClientVersion: Tailcfg.ClientVersion? = null, // Currently unused + var TailFSShares: Map? = null, ) @Serializable @@ -65,15 +61,15 @@ class Ipn { @Serializable data class MaskedPrefs( - var RouteAllSet: Boolean? = null, - var CorpDNSSet: Boolean? = null, - var ExitNodeIDSet: Boolean? = null, - var ExitNodeAllowLANAccessSet: Boolean? = null, - var WantRunningSet: Boolean? = null, - var ShieldsUpSet: Boolean? = null, - var AdvertiseRoutesSet: Boolean? = null, - var ForceDaemonSet: Boolean? = null, - var HostnameSet: Boolean? = null, + var RouteAllSet: Boolean? = null, + var CorpDNSSet: Boolean? = null, + var ExitNodeIDSet: Boolean? = null, + var ExitNodeAllowLANAccessSet: Boolean? = null, + var WantRunningSet: Boolean? = null, + var ShieldsUpSet: Boolean? = null, + var AdvertiseRoutesSet: Boolean? = null, + var ForceDaemonSet: Boolean? = null, + var HostnameSet: Boolean? = null, ) { var RouteAll: Boolean? = null set(value) { @@ -124,39 +120,36 @@ class Ipn { @Serializable data class AutoUpdatePrefs( - var Check: Boolean? = null, - var Apply: Boolean? = null, + var Check: Boolean? = null, + var Apply: Boolean? = null, ) @Serializable data class EngineStatus( - val RBytes: Long, - val WBytes: Long, - val NumLive: Int, - val LivePeers: Map, + val RBytes: Long, + val WBytes: Long, + val NumLive: Int, +// val LivePeers: Map, ) @Serializable data class PartialFile( - val Name: String, - val Started: String, - val DeclaredSize: Long, - val Received: Long, - val PartialPath: String? = null, - var FinalPath: String? = null, - val Done: Boolean? = null, + val Name: String, + val Started: String, + val DeclaredSize: Long, + val Received: Long, + val PartialPath: String? = null, + var FinalPath: String? = null, + val Done: Boolean? = null, ) } class Persist { @Serializable data class Persist( - var PrivateMachineKey: String = - "privkey:0000000000000000000000000000000000000000000000000000000000000000", - var PrivateNodeKey: String = - "privkey:0000000000000000000000000000000000000000000000000000000000000000", - var OldPrivateNodeKey: String = - "privkey:0000000000000000000000000000000000000000000000000000000000000000", - var Provider: String = "", + var PrivateMachineKey: String = "privkey:0000000000000000000000000000000000000000000000000000000000000000", + var PrivateNodeKey: String = "privkey:0000000000000000000000000000000000000000000000000000000000000000", + var OldPrivateNodeKey: String = "privkey:0000000000000000000000000000000000000000000000000000000000000000", + var Provider: String = "", ) } diff --git a/android/src/main/java/com/tailscale/ipn/ui/model/IpnState.kt b/android/src/main/java/com/tailscale/ipn/ui/model/IpnState.kt index 06ec633..02a2898 100644 --- a/android/src/main/java/com/tailscale/ipn/ui/model/IpnState.kt +++ b/android/src/main/java/com/tailscale/ipn/ui/model/IpnState.kt @@ -5,114 +5,15 @@ package com.tailscale.ipn.ui.model import kotlinx.serialization.Serializable -class IpnState { - @Serializable - data class PeerStatusLite( - val RxBytes: Long, - val TxBytes: Long, - val LastHandshake: String, - val NodeKey: String, - ) - - @Serializable - data class PeerStatus( - val ID: StableNodeID, - val HostName: String, - val DNSName: String, - val TailscaleIPs: List? = null, - val Tags: List? = null, - val PrimaryRoutes: List? = null, - val Addrs: List? = null, - val Online: Boolean, - val ExitNode: Boolean, - val ExitNodeOption: Boolean, - val Active: Boolean, - val PeerAPIURL: List? = null, - val Capabilities: List? = null, - val SSH_HostKeys: List? = null, - val ShareeNode: Boolean? = null, - val Expired: Boolean? = null, - val Location: Tailcfg.Location? = null, - ) { - fun computedName(status: Status): String { - val name = DNSName - val suffix = status.CurrentTailnet?.MagicDNSSuffix - - suffix ?: return name - - if (!(name.endsWith("." + suffix + "."))) { - return name - } - - return name.dropLast(suffix.count() + 2) - } - } - - @Serializable - data class ExitNodeStatus( - val ID: StableNodeID, - val Online: Boolean, - val TailscaleIPs: List? = null, - ) - - @Serializable - data class TailnetStatus( - val Name: String, - val MagicDNSSuffix: String, - val MagicDNSEnabled: Boolean, - ) - - @Serializable - data class Status( - val Version: String, - val TUN: Boolean, - val BackendState: String, - val AuthURL: String, - val TailscaleIPs: List? = null, - val Self: PeerStatus? = null, - val ExitNodeStatus: ExitNodeStatus? = null, - val Health: List? = null, - val CurrentTailnet: TailnetStatus? = null, - val CertDomains: List? = null, - val Peer: Map? = null, - val User: Map? = null, - val ClientVersion: Tailcfg.ClientVersion? = null, - ) - - @Serializable - data class NetworkLockStatus( - var Enabled: Boolean, - var PublicKey: String, - var NodeKey: String, - var NodeKeySigned: Boolean, - var FilteredPeers: List? = null, - var StateID: ULong? = null, - ) - - @Serializable - data class TKAFilteredPeer( - var Name: String, - var TailscaleIPs: List, - var NodeKey: String, - ) - - @Serializable - data class PingResult( - var IP: Addr, - var Err: String, - var LatencySeconds: Double, - ) -} - class IpnLocal { @Serializable data class LoginProfile( - var ID: String, - val Name: String, - val Key: String, - val UserProfile: Tailcfg.UserProfile, - val NetworkProfile: Tailcfg.NetworkProfile? = null, - val LocalUserID: String, + var ID: String, + val Name: String, + val Key: String, + val UserProfile: Tailcfg.UserProfile, + val NetworkProfile: Tailcfg.NetworkProfile? = null, + val LocalUserID: String, ) { fun isEmpty(): Boolean { return ID.isEmpty() diff --git a/android/src/main/java/com/tailscale/ipn/ui/model/NetMap.kt b/android/src/main/java/com/tailscale/ipn/ui/model/NetMap.kt index 24aa244..b431bc5 100644 --- a/android/src/main/java/com/tailscale/ipn/ui/model/NetMap.kt +++ b/android/src/main/java/com/tailscale/ipn/ui/model/NetMap.kt @@ -5,51 +5,49 @@ package com.tailscale.ipn.ui.model import kotlinx.serialization.Serializable -class Netmap { - @Serializable - data class NetworkMap( - var SelfNode: Tailcfg.Node, - var NodeKey: KeyNodePublic, - var Peers: List? = null, - var Expiry: Time, - var Domain: String, - var UserProfiles: Map, - var TKAEnabled: Boolean, - var DNS: Tailcfg.DNSConfig? = null - ) { - // Keys are tailcfg.UserIDs thet get stringified - // Helpers - fun currentUserProfile(): Tailcfg.UserProfile? { - return userProfile(User()) - } +@Serializable +data class NetworkMap( + var SelfNode: Tailcfg.Node, +// var NodeKey: KeyNodePublic, // Currently unused + var Peers: List? = null, +// var Expiry: Time, // Currently unused +// var Domain: String, // Currently unused + var UserProfiles: Map, +// var TKAEnabled: Boolean, // Currently unused +// var DNS: Tailcfg.DNSConfig? = null // Currently unused +) { + // Keys are tailcfg.UserIDs thet get stringified + // Helpers + fun currentUserProfile(): Tailcfg.UserProfile? { + return userProfile(User()) + } - fun User(): UserID { - return SelfNode.User - } + fun User(): UserID { + return SelfNode.User + } - fun userProfile(id: Long): Tailcfg.UserProfile? { - return UserProfiles[id.toString()] - } + fun userProfile(id: Long): Tailcfg.UserProfile? { + return UserProfiles[id.toString()] + } - fun getPeer(id: StableNodeID): Tailcfg.Node? { - if(id == SelfNode.StableID) { - return SelfNode - } - return Peers?.find { it.StableID == id } + fun getPeer(id: StableNodeID): Tailcfg.Node? { + if (id == SelfNode.StableID) { + return SelfNode } + return Peers?.find { it.StableID == id } + } - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other !is NetworkMap) return false - - return SelfNode == other.SelfNode && - NodeKey == other.NodeKey && - Peers == other.Peers && - Expiry == other.Expiry && - User() == other.User() && - Domain == other.Domain && - UserProfiles == other.UserProfiles && - TKAEnabled == other.TKAEnabled - } + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is NetworkMap) return false + + return SelfNode == other.SelfNode && +// NodeKey == other.NodeKey && + Peers == other.Peers && +// Expiry == other.Expiry && + User() == other.User() && +// Domain == other.Domain && + UserProfiles == other.UserProfiles +// TKAEnabled == other.TKAEnabled } } diff --git a/android/src/main/java/com/tailscale/ipn/ui/model/TailCfg.kt b/android/src/main/java/com/tailscale/ipn/ui/model/TailCfg.kt index baa417f..9c92e95 100644 --- a/android/src/main/java/com/tailscale/ipn/ui/model/TailCfg.kt +++ b/android/src/main/java/com/tailscale/ipn/ui/model/TailCfg.kt @@ -6,22 +6,23 @@ package com.tailscale.ipn.ui.model import kotlinx.serialization.Serializable class Tailcfg { - @Serializable - data class ClientVersion( - var RunningLatest: Boolean? = null, - var LatestVersion: String? = null, - var UrgentSecurityUpdate: Boolean? = null, - var Notify: Boolean? = null, - var NotifyURL: String? = null, - var NotifyText: String? = null - ) + // Currently unused +// @Serializable +// data class ClientVersion( +// var RunningLatest: Boolean? = null, +// var LatestVersion: String? = null, +// var UrgentSecurityUpdate: Boolean? = null, +// var Notify: Boolean? = null, +// var NotifyURL: String? = null, +// var NotifyText: String? = null +// ) @Serializable data class UserProfile( - val ID: Long, - val DisplayName: String, - val LoginName: String, - val ProfilePicURL: String? = null, + val ID: Long, + val DisplayName: String, + val LoginName: String, + val ProfilePicURL: String? = null, ) { fun isTaggedDevice(): Boolean { return LoginName == "tagged-devices" @@ -30,48 +31,48 @@ class Tailcfg { @Serializable data class Hostinfo( - var IPNVersion: String? = null, - var FrontendLogID: String? = null, - var BackendLogID: String? = null, - var OS: String? = null, - var OSVersion: String? = null, - var Env: String? = null, - var Distro: String? = null, - var DistroVersion: String? = null, - var DistroCodeName: String? = null, - var Desktop: Boolean? = null, - var Package: String? = null, - var DeviceModel: String? = null, - var ShareeNode: Boolean? = null, - var Hostname: String? = null, - var ShieldsUp: Boolean? = null, - var NoLogsNoSupport: Boolean? = null, - var Machine: String? = null, - var RoutableIPs: List? = null, - var Services: List? = null, - var Location: Location? = null, +// var IPNVersion: String? = null, // Currently unused +// var FrontendLogID: String? = null, // Currently unused +// var BackendLogID: String? = null, // Currently unused + var OS: String? = null, +// var OSVersion: String? = null, // Currently unused +// var Env: String? = null, // Currently unused +// var Distro: String? = null, // Currently unused +// var DistroVersion: String? = null, // Currently unused +// var DistroCodeName: String? = null, // Currently unused +// var Desktop: Boolean? = null, // Currently unused +// var Package: String? = null, // Currently unused +// var DeviceModel: String? = null, // Currently unused +// var ShareeNode: Boolean? = null, // Currently unused +// var Hostname: String? = null, // Currently unused +// var ShieldsUp: Boolean? = null, // Currently unused +// var NoLogsNoSupport: Boolean? = null, // Currently unused +// var Machine: String? = null, // Currently unused +// var RoutableIPs: List? = null, // Currently unused +// var Services: List? = null, // Currently unused + var Location: Location? = null, ) @Serializable data class Node( - var ID: NodeID, - var StableID: StableNodeID, - var Name: String, - var User: UserID, - var Sharer: UserID? = null, - var Key: KeyNodePublic, - var KeyExpiry: String, - var Machine: MachineKey, - var Addresses: List? = null, - var AllowedIPs: List? = null, - var Endpoints: List? = null, - var Hostinfo: Hostinfo, - var Created: Time, - var LastSeen: Time? = null, - var Online: Boolean? = null, - var Capabilities: List? = null, - var ComputedName: String, - var ComputedNameWithHost: String +// var ID: NodeID, // Currently unused + var StableID: StableNodeID, + var Name: String, + var User: UserID, +// var Sharer: UserID? = null, // Currently unused +// var Key: KeyNodePublic, // Currently unused + var KeyExpiry: String, +// var Machine: MachineKey, // Currently unused + var Addresses: List? = null, + var AllowedIPs: List? = null, +// var Endpoints: List? = null, // Currently unused + var Hostinfo: Hostinfo, +// var Created: Time, // Currently unused +// var LastSeen: Time? = null, // Currently unused + var Online: Boolean? = null, + var Capabilities: List? = null, + var ComputedName: String, +// var ComputedNameWithHost: String // Currently unused ) { val isAdmin: Boolean get() = (Capabilities ?: emptyList()).contains("https://tailscale.com/cap/is-admin") @@ -81,27 +82,29 @@ class Tailcfg { AllowedIPs?.contains("0.0.0.0/0") ?: false && AllowedIPs?.contains("::/0") ?: false } - @Serializable - data class Service(var Proto: String, var Port: Int, var Description: String? = null) + // Currently unused +// @Serializable +// data class Service(var Proto: String, var Port: Int, var Description: String? = null) @Serializable data class NetworkProfile(var MagicDNSName: String? = null, var DomainName: String? = null) @Serializable data class Location( - var Country: String? = null, - var CountryCode: String? = null, - var City: String? = null, - var CityCode: String? = null, - var Priority: Int? = null + var Country: String? = null, + var CountryCode: String? = null, + var City: String? = null, +// var CityCode: String? = null, // Currently unused + var Priority: Int? = null ) - @Serializable - data class DNSConfig( - var Resolvers: List? = null, - var Routes: Map?>? = null, - var FallbackResolvers: List? = null, - var Domains: List? = null, - var Nameservers: List? = null - ) + // Currently unused +// @Serializable +// data class DNSConfig( +// var Resolvers: List? = null, +// var Routes: Map?>? = null, +// var FallbackResolvers: List? = null, +// var Domains: List? = null, +// var Nameservers: List? = null +// ) } diff --git a/android/src/main/java/com/tailscale/ipn/ui/model/Types.kt b/android/src/main/java/com/tailscale/ipn/ui/model/Types.kt index 67ab28c..6695351 100644 --- a/android/src/main/java/com/tailscale/ipn/ui/model/Types.kt +++ b/android/src/main/java/com/tailscale/ipn/ui/model/Types.kt @@ -7,11 +7,11 @@ import kotlinx.serialization.Serializable typealias Addr = String typealias Prefix = String -typealias NodeID = Long -typealias KeyNodePublic = String -typealias MachineKey = String +//typealias NodeID = Long // Currently unused +//typealias KeyNodePublic = String // Currently unused +//typealias MachineKey = String // Currently unused typealias UserID = Long -typealias Time = String +//typealias Time = String // Currently unused typealias StableNodeID = String typealias BugReportID = String diff --git a/android/src/main/java/com/tailscale/ipn/ui/notifier/Notifier.kt b/android/src/main/java/com/tailscale/ipn/ui/notifier/Notifier.kt index b74cf64..8313044 100644 --- a/android/src/main/java/com/tailscale/ipn/ui/notifier/Notifier.kt +++ b/android/src/main/java/com/tailscale/ipn/ui/notifier/Notifier.kt @@ -6,7 +6,7 @@ package com.tailscale.ipn.ui.notifier import android.util.Log import com.tailscale.ipn.ui.model.Ipn import com.tailscale.ipn.ui.model.Ipn.Notify -import com.tailscale.ipn.ui.model.Netmap +import com.tailscale.ipn.ui.model.NetworkMap import com.tailscale.ipn.ui.util.set import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.CoroutineScope @@ -32,7 +32,7 @@ object Notifier { private val isReady = CompletableDeferred() val state: StateFlow = MutableStateFlow(Ipn.State.NoState) - val netmap: StateFlow = MutableStateFlow(null) + val netmap: StateFlow = MutableStateFlow(null) val prefs: StateFlow = MutableStateFlow(null) val engineStatus: StateFlow = MutableStateFlow(null) val tailFSShares: StateFlow?> = MutableStateFlow(null) diff --git a/android/src/main/java/com/tailscale/ipn/ui/util/PeerHelper.kt b/android/src/main/java/com/tailscale/ipn/ui/util/PeerHelper.kt index 096b4db..303084e 100644 --- a/android/src/main/java/com/tailscale/ipn/ui/util/PeerHelper.kt +++ b/android/src/main/java/com/tailscale/ipn/ui/util/PeerHelper.kt @@ -4,7 +4,7 @@ package com.tailscale.ipn.ui.util -import com.tailscale.ipn.ui.model.Netmap +import com.tailscale.ipn.ui.model.NetworkMap import com.tailscale.ipn.ui.model.Tailcfg import com.tailscale.ipn.ui.model.UserID import com.tailscale.ipn.ui.notifier.Notifier @@ -37,7 +37,7 @@ class PeerCategorizer(scope: CoroutineScope) { } } - private fun regenerateGroupedPeers(netmap: Netmap.NetworkMap): List { + private fun regenerateGroupedPeers(netmap: NetworkMap): List { val peers: List = netmap.Peers ?: return emptyList() val selfNode = netmap.SelfNode var grouped = mutableMapOf>()