Skip to content
This repository was archived by the owner on Dec 18, 2022. It is now read-only.

Commit 0a18dd7

Browse files
authored
Merge pull request #51 from 05nelsonm/mn/feature/tor-service-event-broadcaster
Adds broadcasting of Tor's port information to the application
2 parents e3e52fe + aa28fa5 commit 0a18dd7

File tree

9 files changed

+245
-20
lines changed

9 files changed

+245
-20
lines changed

sampleapp/src/main/java/io/matthewnelson/sampleapp/MyEventBroadcaster.kt

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,61 @@ package io.matthewnelson.sampleapp
6868

6969
import androidx.lifecycle.LiveData
7070
import androidx.lifecycle.MutableLiveData
71-
import io.matthewnelson.topl_core_base.EventBroadcaster
71+
import io.matthewnelson.topl_core_base.BaseConsts
72+
import io.matthewnelson.topl_service.service.components.onionproxy.TorServiceEventBroadcaster
7273
import io.matthewnelson.topl_service.util.ServiceUtilities
7374

7475
/**
7576
* @suppress
77+
* @see [TorServiceEventBroadcaster]
78+
* @see [io.matthewnelson.topl_core_base.EventBroadcaster]
7679
* */
77-
class MyEventBroadcaster: EventBroadcaster() {
80+
class MyEventBroadcaster: TorServiceEventBroadcaster() {
81+
82+
83+
//////////////////////////
84+
/// ControlPortAddress ///
85+
//////////////////////////
86+
87+
// Make Volatile so that if referencing on a different thread, we get
88+
// the update immediately
89+
@Volatile
90+
var controlPortAddress: String? = null
91+
private set
92+
93+
override fun broadcastControlPortAddress(controlPortAddress: String?) {
94+
this.controlPortAddress = controlPortAddress
95+
}
96+
97+
98+
////////////////////////
99+
/// SocksPortAddress ///
100+
////////////////////////
101+
102+
// Make Volatile so that if referencing on a different thread, we get
103+
// the update immediately
104+
@Volatile
105+
var socksPortAddress: String? = null
106+
private set
107+
108+
override fun broadcastSocksPortAddress(socksPortAddress: String?) {
109+
this.socksPortAddress = socksPortAddress
110+
}
111+
112+
113+
///////////////////////
114+
/// HttpPortAddress ///
115+
///////////////////////
116+
117+
// Make Volatile so that if referencing on a different thread, we get
118+
// the update immediately
119+
@Volatile
120+
var httpPortAddress: String? = null
121+
private set
122+
123+
override fun broadcastHttpPortAddress(httpPortAddress: String?) {
124+
this.httpPortAddress = httpPortAddress
125+
}
78126

79127

80128
/////////////////
@@ -137,15 +185,15 @@ class MyEventBroadcaster: EventBroadcaster() {
137185
///////////////////
138186
inner class TorStateData(val state: String, val networkState: String)
139187

140-
private var lastState = TorState.OFF
141-
private var lastNetworkState = TorNetworkState.DISABLED
188+
private var lastState = BaseConsts.TorState.OFF
189+
private var lastNetworkState = BaseConsts.TorNetworkState.DISABLED
142190

143191
private val _liveTorState = MutableLiveData<TorStateData>(
144192
TorStateData(lastState, lastNetworkState)
145193
)
146194
val liveTorState: LiveData<TorStateData> = _liveTorState
147195

148-
override fun broadcastTorState(@TorState state: String, @TorNetworkState networkState: String) {
196+
override fun broadcastTorState(@BaseConsts.TorState state: String, @BaseConsts.TorNetworkState networkState: String) {
149197
if (state == lastState && networkState == lastNetworkState) return
150198

151199
lastState = state

sampleapp/src/main/java/io/matthewnelson/sampleapp/MyTorSettings.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ package io.matthewnelson.sampleapp
6969
import io.matthewnelson.topl_core_base.TorSettings
7070

7171
/**
72-
* See [TorSettings] for comments on what is what.
7372
* @suppress
73+
* @see [TorSettings]
7474
* */
7575
class MyTorSettings: TorSettings() {
7676

@@ -93,7 +93,7 @@ class MyTorSettings: TorSettings() {
9393
get() = DEFAULT__EXIT_NODES
9494

9595
override val httpTunnelPort: String
96-
get() = DEFAULT__HTTP_TUNNEL_PORT
96+
get() = "auto"
9797

9898
override val listOfSupportedBridges: List<@SupportedBridges String>
9999
get() = arrayListOf(SupportedBridges.MEEK, SupportedBridges.OBFS4)
@@ -129,7 +129,7 @@ class MyTorSettings: TorSettings() {
129129
get() = null
130130

131131
override val socksPort: String
132-
get() = "9051"
132+
get() = "auto"
133133

134134
override val virtualAddressNetwork: String?
135135
get() = "10.192.0.2/10"

topl-core-base/build.gradle

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ dokka {
4242
includeNonPublic = false
4343
skipEmptyPackages = true
4444
samples = [
45-
"$rootDir/sampleapp/src/main/java/io/matthewnelson/sampleapp/App.kt".toString()
45+
"$rootDir/sampleapp/src/main/java/io/matthewnelson/sampleapp/App.kt".toString(),
46+
"$rootDir/topl-service/src/main/java/io/matthewnelson/topl_service/service/components/onionproxy/ServiceEventBroadcaster.kt".toString()
4647
]
4748
sourceLink {
4849
url = "https://github.com/05nelsonm/TorOnionProxyLibrary-Android/blob/master/"

topl-core-base/src/main/java/io/matthewnelson/topl_core_base/EventBroadcaster.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ package io.matthewnelson.topl_core_base
9696
* allows for easier separation of messages based on the type, process or class.
9797
*
9898
* See [BaseConsts.BroadcastType]s
99+
* @sample [io.matthewnelson.topl_service.service.components.onionproxy.ServiceEventBroadcaster]
99100
*/
100101
abstract class EventBroadcaster: BaseConsts() {
101102

topl-core-base/src/main/java/io/matthewnelson/topl_core_base/TorSettings.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,12 +176,14 @@ abstract class TorSettings: BaseConsts() {
176176
abstract val exitNodes: String?
177177

178178
/**
179+
* Could be "auto" or a specific port, such as "8288".
180+
*
179181
* TorBrowser and Orbot use "8218" by default. It may be wise to pick something
180182
* that won't conflict if you're using this setting.
181183
*
182184
* Docs: https://2019.www.torproject.org/docs/tor-manual.html.en#HTTPTunnelPort
183185
*
184-
* See [DEFAULT__HTTP_TUNNEL_PORT]
186+
* See [DEFAULT__HTTP_TUNNEL_PORT] ("0", to disable it)
185187
*
186188
* TODO: Change to List<String> and update TorSettingsBuilder method for
187189
* multi-port support.
@@ -262,7 +264,7 @@ abstract class TorSettings: BaseConsts() {
262264
abstract val relayPort: Int?
263265

264266
/**
265-
* Could be "auto" or a specified port, such as "9051".
267+
* Could be "auto" or a specific port, such as "9051".
266268
*
267269
* TorBrowser uses "9150", and Orbot uses "9050" by default. It may be wise
268270
* to pick something that won't conflict.

topl-service/build.gradle

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ dokka {
4444
includeNonPublic = false
4545
skipEmptyPackages = true
4646
samples = [
47-
"$rootDir/sampleapp/src/main/java/io/matthewnelson/sampleapp/App.kt".toString()
47+
"$rootDir/sampleapp/src/main/java/io/matthewnelson/sampleapp/App.kt".toString(),
48+
"$rootDir/sampleapp/src/main/java/io/matthewnelson/sampleapp/MyEventBroadcaster.kt".toString()
4849
]
4950
sourceLink {
5051
url = "https://github.com/05nelsonm/TorOnionProxyLibrary-Android/blob/master/"

topl-service/src/main/java/io/matthewnelson/topl_service/TorServiceController.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ import io.matthewnelson.topl_service.service.components.binding.BaseServiceConne
7979
import io.matthewnelson.topl_service.service.components.actions.ServiceActionProcessor
8080
import io.matthewnelson.topl_service.service.components.actions.ServiceActions
8181
import io.matthewnelson.topl_service.service.components.binding.TorServiceConnection
82+
import io.matthewnelson.topl_service.service.components.onionproxy.TorServiceEventBroadcaster
8283
import io.matthewnelson.topl_service.util.ServiceConsts
8384

8485
class TorServiceController private constructor(): ServiceConsts() {
@@ -134,7 +135,7 @@ class TorServiceController private constructor(): ServiceConsts() {
134135
private val geoip6AssetPath: String
135136
) {
136137

137-
private var appEventBroadcaster: EventBroadcaster? = Companion.appEventBroadcaster
138+
private var appEventBroadcaster: TorServiceEventBroadcaster? = Companion.appEventBroadcaster
138139
// private var heartbeatTime = BackgroundManager.heartbeatTime
139140
private var restartTorDelayTime = ServiceActionProcessor.restartTorDelayTime
140141
private var stopServiceDelayTime = ServiceActionProcessor.stopServiceDelayTime
@@ -240,7 +241,7 @@ class TorServiceController private constructor(): ServiceConsts() {
240241
* NOTE: You will, ofc, have to cast [Companion.appEventBroadcaster] as whatever your
241242
* class actually is.
242243
* */
243-
fun setEventBroadcaster(eventBroadcaster: EventBroadcaster): Builder {
244+
fun setEventBroadcaster(eventBroadcaster: TorServiceEventBroadcaster): Builder {
244245
this.appEventBroadcaster = eventBroadcaster
245246
return this
246247
}
@@ -306,7 +307,7 @@ class TorServiceController private constructor(): ServiceConsts() {
306307
* Where everything needed to interact with [TorService] resides.
307308
* */
308309
companion object {
309-
var appEventBroadcaster: EventBroadcaster? = null
310+
var appEventBroadcaster: TorServiceEventBroadcaster? = null
310311
private set
311312

312313
/**

topl-service/src/main/java/io/matthewnelson/topl_service/service/components/onionproxy/ServiceEventBroadcaster.kt

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
package io.matthewnelson.topl_service.service.components.onionproxy
6868

6969
import io.matthewnelson.topl_core.OnionProxyManager
70+
import io.matthewnelson.topl_core.listener.BaseEventListener
7071
import io.matthewnelson.topl_core_base.EventBroadcaster
7172
import io.matthewnelson.topl_service.TorServiceController
7273
import io.matthewnelson.topl_service.service.BaseService
@@ -205,29 +206,48 @@ internal class ServiceEventBroadcaster(private val torService: BaseService): Eve
205206
private fun isBootstrappingComplete(): Boolean =
206207
bootstrapProgress == "Bootstrapped 100%"
207208

209+
@Volatile
210+
private var controlPort: String? = null
211+
@Volatile
212+
private var httpTunnelPort: String? = null
213+
@Volatile
214+
private var socksPort: String? = null
215+
208216
override fun broadcastNotice(msg: String) {
209217

210218
when {
219+
// ServiceActionProcessor
220+
msg.contains(ServiceActionProcessor::class.java.simpleName) -> {
221+
handleServiceActionProcessorMsg(msg)
222+
}
211223
// BOOTSTRAPPED
212-
// NOTICE|BaseEventListener|Bootstrapped 5% (conn): Connecting to a relay
213224
msg.contains("Bootstrapped") -> {
214225
handleBootstrappedMsg(msg)
215226
}
227+
// Control Port
228+
msg.contains("Successfully connected to Control Port:") -> {
229+
handleControlPortMsg(msg)
230+
}
231+
// Http Tunnel Port
232+
msg.contains("Opened HTTP tunnel listener on ") -> {
233+
handleHttpTunnelPortMsg(msg)
234+
}
235+
// Socks Port
236+
msg.contains("Opened Socks listener on ") -> {
237+
handleSocksPortMsg(msg)
238+
}
216239
// NEWNYM
217240
msg.contains(TorControlCommands.SIGNAL_NEWNYM) -> {
218241
handleNewNymMsg(msg)
219242
}
220-
// ServiceActionProcessor
221-
msg.contains(ServiceActionProcessor::class.java.simpleName) -> {
222-
handleServiceActionProcessorMsg(msg)
223-
}
224243
}
225244

226245
TorServiceController.appEventBroadcaster?.let {
227246
scopeMain.launch { it.broadcastNotice(msg) }
228247
}
229248
}
230249

250+
// NOTICE|BaseEventListener|Bootstrapped 5% (conn): Connecting to a relay
231251
private fun handleBootstrappedMsg(msg: String) {
232252
val msgSplit = msg.split(" ")
233253
msgSplit.elementAtOrNull(2)?.let {
@@ -237,6 +257,7 @@ internal class ServiceEventBroadcaster(private val torService: BaseService): Eve
237257
torService.updateNotificationContentText(bootstrapped)
238258

239259
if (bootstrapped == "Bootstrapped 100%") {
260+
updateAppEventBroadcasterWithPortInfo()
240261
torService.updateNotificationIcon(NotificationImage.ENABLED)
241262
torService.updateNotificationProgress(true, 100)
242263
torService.updateNotificationProgress(false, null)
@@ -257,6 +278,24 @@ internal class ServiceEventBroadcaster(private val torService: BaseService): Eve
257278
}
258279
}
259280

281+
// NOTICE|OnionProxyManager|Successfully connected to Control Port: 44201
282+
private fun handleControlPortMsg(msg: String) {
283+
val port = msg.split(":")[1].trim()
284+
controlPort = "127.0.0.1:$port"
285+
}
286+
287+
// NOTICE|BaseEventListener|Opened HTTP tunnel listener on 127.0.0.1:37397
288+
private fun handleHttpTunnelPortMsg(msg: String) {
289+
val port = msg.split(":")[1].trim()
290+
httpTunnelPort = "127.0.0.1:$port"
291+
}
292+
293+
// NOTICE|BaseEventListener|Opened Socks listener on 127.0.0.1:9051
294+
private fun handleSocksPortMsg(msg: String) {
295+
val port = msg.split(":")[1].trim()
296+
socksPort = "127.0.0.1:$port"
297+
}
298+
260299
private fun handleNewNymMsg(msg: String) {
261300
val msgToShow: String? =
262301
when {
@@ -300,6 +339,16 @@ internal class ServiceEventBroadcaster(private val torService: BaseService): Eve
300339
}
301340
}
302341

342+
private fun updateAppEventBroadcasterWithPortInfo() {
343+
TorServiceController.appEventBroadcaster?.let {
344+
scopeMain.launch {
345+
it.broadcastControlPortAddress(controlPort)
346+
it.broadcastHttpPortAddress(httpTunnelPort)
347+
it.broadcastSocksPortAddress(socksPort)
348+
}
349+
}
350+
}
351+
303352
/**
304353
* Display a message in the notification's ContentText space for the defined
305354
* [delayMilliSeconds], after which (if Tor is connected), publish to the Notification's
@@ -335,6 +384,10 @@ internal class ServiceEventBroadcaster(private val torService: BaseService): Eve
335384
override fun broadcastTorState(@TorState state: String, @TorNetworkState networkState: String) {
336385
if (torState == TorState.ON && state != torState) {
337386
bootstrapProgress = ""
387+
controlPort = null
388+
httpTunnelPort = null
389+
socksPort = null
390+
updateAppEventBroadcasterWithPortInfo()
338391
torService.removeNotificationActions()
339392
}
340393

0 commit comments

Comments
 (0)