Expand description
§Obfs4 Connection Checker
This small tool attempts to check obfs4 bridge status over a long period of time.
A large list of bridges is intended to be ingested into the program once, and then another endpoint is meant to be polled in order to get updates on those bridges’ states.
§Usage
Launch the program by running cargo run
Then, to pass bridges into the program for an initial scan, make the following HTTP POST request.
Here is the curl
command:
curl -X POST localhost:5000/bridge-state -H "Content-Type: application/json" -d '{"bridge_lines": ["BRIDGE_LINE"]}'
where you should replace BRIDGE_LINE
by all the bridges that you wish to test
The output would look something like this:
{
"bridge_results": {
"obfs4 45.145.95.6:27015 C5B7CD6946FF10C5B3E89691A7D3F2C122D2117C cert=TD7PbUO0/0k6xYHMPW3vJxICfkMZNdkRrb63Zhl5j9dW3iRGiCx0A7mPhe5T2EDzQ35+Zw iat-mode=0": {
"functional": false,
"last_tested": "2023-08-16T05:44:06.906005329Z",
"error": "Channel for [scrubbed] timed out"
},
"obfs4 37.218.245.14:38224 D9A82D2F9C2F65A18407B1D2B764F130847F8B5D cert=bjRaMrr1BRiAW8IE9U5z27fQaYgOhX1UCmOpg2pFpoMvo6ZgQMzLsaTzzQNTlm7hNcb+Sg iat-mode=0": {
"functional": false,
"last_tested": "2023-08-16T05:44:06.905914678Z",
"error": "Network IO error, or TLS error, in TLS negotiation, talking to Some([scrubbed]): unexpected EOF"
},
"obfs4 192.95.36.142:443 CDF2E852BF539B82BD10E27E9115A31734E378C2 cert=qUVQ0srL1JI/vO6V6m/24anYXiJD3QP2HgzUKQtQ7GRqqUvs7P+tG43RtAqdhLOALP7DJQ iat-mode=1": {
"functional": true,
"last_tested": "2023-08-16T05:44:06.905823776Z"
}
},
"time": 21
}
For getting updates, right now we have a /updates
GET endpoint that you can poll for updates.
For that you can run
curl localhost:5000/updates
This has the same output structure as the /bridge-state
endpoint.
To add additional bridges for testing, call /add-bridges
. It is a POST endpoint which takes
the bridge list in the same manner as /bridge-state
, and only returns a status code indicating
success or failure. From there on, poll /updates
as usual to get connection info.
§Usage Disclaimers
Note that this tool is currently in active development and needs further work and feedback from the Tor Project devs in order to one day make it to production
Note that /updates
often may return an empty list, but that is because at that point
there may not be updates to give to the user. This is why you should poll this
endpoint for responses. If we call this endpoint before /bridge-state
, you
will always get no results.
Hence you should ALWAYS call /bridge-state
first and poll /updates
thereafter.
Also only call /bridge-state
once, because /bridge-state
calls also launch
tasks which keep tabs on the bridges that you pass through that API, and calling
it more than once will create more and more tasks. This won’t lead to any real
benefit, and /updates
won’t give the right updates to you.
§Design Notes
The current design does leave something to be desired, as the usage disclaimer section indicates. Here are some alternative design patterns/thoughts for this program that can be explored in the future:
-
Create one endpoint to create a list/override existing list of bridges with a new list, and then /bridge-state can be called to get the initial impression of all the bridges.
Once this is done maybe there is a way to make all future invocations of /bridge-state just be what /updates currently does.
-
Alternatively, we can at least prevent /updates from being called before /bridge-state or /bridge-state be called more than once
-
Decouple /updates from /bridge-state (can we make /updates do the initial set up, instead of expecting it to be manually initiated via /bridge-state?), and make it possible to get updates for multiple sets of bridges (not just the initial set requested via /bridge-state)
For example, it should be possible to POST to /bridge-state more than once (maybe we want to monitor multiple sets of bridges). Maybe we can make the /bridge-state endpoint return a UUID that users can then pass to the /updates endpoint to get updates for a particular bridge set
- Why do we need to deliver deltas? Wouldn’t it be easier to have the client check the status of the bridges they’re interested in (using /bridge-state), and let them compute the deltas themselves (or using a separate post-processing tool)?
Modules§
- checking 🔒
- This module contains the code that actually runs checks on bridges
Structs§
- Args 🔒
- Utility to deliver real-time updates on bridge health
- Bridge
Lines 🔒 - The input to our
bridge-state
handler - Bridge
Result - Struct which represents one bridge’s result
- Bridges
Result 🔒 - The output to our
bridge-state
handler
Functions§
- add_
new_ 🔒bridges - Add new bridges to the main testing tasks
- check_
bridges 🔒 - Wrapper around the main testing function
- main 🔒
- Run the HTTP server and call the required methods to initialize the testing
- updates 🔒
- Wrapper around the main testing function