|
|
|
|
|
# Table of Contents
|
|
|
|
|
|
1. [Motivation](#orgb77977c)
|
|
|
2. [Transport Layers](#org3c3c551)
|
|
|
1. [API Map](#orgf6c8f50)
|
|
|
2. [Device Map](#orgc7deb77)
|
|
|
3. [Source Code](#org061007d)
|
|
|
4. [Automation Suite](#org761cf0a)
|
|
|
5. [Simulating Internet Shutdowns](#org1439fc1)
|
|
|
1. [Experiment setup](#orgea14985)
|
|
|
2. [1. Fake captive portal](#orgec4a93a)
|
|
|
3. [2. Manipulating DNS responses for some of Google’s domains](#orgfea69a7)
|
|
|
4. [Summary](#orgf1c44aa)
|
|
|
6. [Bluetooth](#org7e41f02)
|
|
|
1. [Resources](#org0962a9c)
|
|
|
2. [BLE](#org3c75e90)
|
|
|
3. [BLESSED](#org0117473)
|
|
|
4. [BLE Allocator Characteristic](#org4b874c2)
|
|
|
5. [BluetoothCommunicator](#org970e8d5)
|
|
|
7. [WiFi](#org18dfbcb)
|
|
|
1. [Network Service Discovery (NSD)](#orge1b6347)
|
|
|
2. [Local Service Discovery (LSD)](#org7e86006)
|
|
|
3. [WiFi Client](#org38f6c2d)
|
|
|
4. [WiFi Direct](#orga6da152)
|
|
|
8. [Alternative Transports](#org7efd1ad)
|
|
|
9. [Future Considerations](#org12ba11d)
|
|
|
1. [Mix-and-Match Transport Layers](#org2e599ad)
|
|
|
2. [Evaluate Briar's Threat Model](#org06644e6)
|
|
|
3. [Transport Energy Draw Experiments](#orge2804d6)
|
|
|
3. [Routing Protocols [WIP]](#org8e12274)
|
|
|
1. [Existing Research](#orgd01fde7)
|
|
|
4. [UI/UX Research [WIP]](#orgd77c49e)
|
|
|
1. [Security Profiles](#org63e0a5d)
|
|
|
2. [Connectivity Profiles](#orgcec3fe9)
|
|
|
5. [Appendix](#org65e3ac0)
|
|
|
1. [Similar Projects](#org3415686)
|
|
|
1. [Community and mesh networks:](#org69796f3)
|
|
|
2. [Darknet and friend-to-friend projects:](#orgcb9e9e6)
|
|
|
3. [Social P2P projects:](#orge011c69)
|
|
|
4. [Sneakernets and DTN:](#org58cb9af)
|
|
|
|
|
|
Public Mesh Research
|
|
|
|
|
|
by The Briar Team
|
|
|
|
|
|
|
|
|
<a id="orgb77977c"></a>
|
|
|
|
|
|
# Motivation
|
|
|
|
|
|
Over the lifetime of the Briar project, the Briar messaging app, and its underlying data synchronization protocol, Bramble, has operated using a "one-hop social mesh" data propagation protocol.
|
|
|
All private messages in the current implementation of Briar, are only delivered directly to the intended recipient.
|
|
|
This design choice allows Briar to hide peer discovery from anyone who is not existing Briar contacts with the user.
|
|
|
Non-contacts, in theory, are unable to prove that the target user is even running the Briar application by sniffing the target's Bluetooth, LAN, or Tor traffic.
|
|
|
This protocol design offers strong privacy and security benefits, however it removes the opportunity for messages to "hop" across mutual Briar contacts, or to other nearby entrusted Briar users.
|
|
|
For transports with short effective range like Bluetooth, a one-hop social mesh propagation strategy is potentially harmful to the message delivery rate.
|
|
|
To potentially improve connectivity in internet shutdown scenarios, the Briar team is conducting research on using "social mesh" and "public mesh" propagation strategies for messages.
|
|
|
This research covers the Briar team's findings for public mesh propagation.
|
|
|
|
|
|
|
|
|
<a id="org3c3c551"></a>
|
|
|
|
|
|
# Transport Layers
|
|
|
|
|
|
The base layer of any mesh networking protocol is the individual direct connections between peer devices. In this section we explore a set of possible transport layers for discovering, and connecting to peer devices. The target for this research is primarily mobile-friendly protocols, however support for other computing devices is also worth considering.
|
|
|
|
|
|
|
|
|
<a id="orgf6c8f50"></a>
|
|
|
|
|
|
## API Map
|
|
|
|
|
|
[TODO] fix md table
|
|
|
|
|
|
|
|
|
<a id="orgc7deb77"></a>
|
|
|
|
|
|
## Device Map
|
|
|
|
|
|
Moto G 4G, Huawei P8 Lite 2015, Samsung J5 2016, Huawei Y6P, Samsung Galaxy A21s and Sony XZ2
|
|
|
[TODO] fix md table
|
|
|
|
|
|
|
|
|
<a id="org061007d"></a>
|
|
|
|
|
|
## Source Code
|
|
|
|
|
|
All of the source code for this project can be found in the [Public Mesh Testbed project](https://code.briarproject.org/briar/public-mesh-testbed) on Briar Project's website. As a way of managing the many different transport layers we are testing for in this project, we use different git branches to represent different transport-layer properties.
|
|
|
|
|
|
|
|
|
<a id="org761cf0a"></a>
|
|
|
|
|
|
## Automation Suite
|
|
|
|
|
|
Testing mesh networking software is often challenging from a developer's perspective because it usually entails juggling handfuls of hardware devices. In order to make it easier to create replicatable testing environments for our software, we started experimenting with Google's Mobly framework, which allows us to run replicatable p2p mesh test suites on sets of hardware devices. This is still a work-in-progress, you can track updates here: <https://code.briarproject.org/briar/public-mesh-research/-/issues/18>
|
|
|
|
|
|
|
|
|
<a id="org1439fc1"></a>
|
|
|
|
|
|
## Simulating Internet Shutdowns
|
|
|
|
|
|
One aspect of our public mesh research is looking into how Android devices behave in case of an Internet shutdown. While it is clear that during a full or partial Internet shutdown, many websites and services cannot be reached from any device, it is not so clear which functionality remains intact. The Android operating system has mechanisms to detect whether a device has a working Internet connection, and we wanted to find out whether this assessment might prevent installed apps from communicating with servers that were technically still reachable.
|
|
|
|
|
|
To get insight into this, we decided to simulate Internet shutdowns on a wireless network using different techniques, and to observe how Android devices reacted while connected to that Wi-Fi.
|
|
|
|
|
|
The experiments showed that it is relatively simple to simulate a partial Internet shutdown where Android thinks the Internet connection is not working, but this does not seem to prevent any non-blocked Internet traffic. The operating system and the browser give strong visual indications to the user that the current Wi-Fi network doesn’t provide Internet access, but the browser and other apps just keep working nonetheless.
|
|
|
|
|
|
This is good news for apps like Briar that are designed to operate during Internet shutdowns, making use of whatever network connectivity is available.
|
|
|
|
|
|
|
|
|
<a id="orgea14985"></a>
|
|
|
|
|
|
### Experiment setup
|
|
|
|
|
|
The basic setup for our experiments was a Linux-based Wi-Fi router that was configured in different ways to simulate an Internet shutdown. A phone running Android 11 was used for testing. The idea was to block just enough of the network to make Android think the Internet connection was broken, and then test whether apps could still use the network.
|
|
|
|
|
|
We already knew that a special domain name was used for checking Internet connectivity: connectivitycheck.gstatic.com. Android uses this domain to test whether the phone is connected to a Wi-Fi network with a so-called captive portal, where the user needs to accept some terms and conditions before gaining Internet access. We manipulated the DNS server to behave in different ways for that special domain name and created four distinct situations:
|
|
|
|
|
|
Install a fake captive portal reachable at connectivitycheck.gstatic.com.
|
|
|
No captive portal, instead configure the DNS server to behave irregularly for connectivitycheck.gstatic.com and some more of Google’s domains:
|
|
|
a) return unused IP addresses,
|
|
|
b) return DNS error responses,
|
|
|
c) do not return DNS responses at all.
|
|
|
|
|
|
A combination of dnsmasq, nginx and iptables was used to set up these situations.
|
|
|
|
|
|
|
|
|
<a id="orgec4a93a"></a>
|
|
|
|
|
|
### 1. Fake captive portal
|
|
|
|
|
|
If you’ve used an Android phone on a public Wi-Fi network, you’re probably familiar with the basic situation created by setup 1). Right after establishing a connection to the Wi-Fi, Android shows a notification telling you that you’re required to sign in to the network in order to use it. The wireless connections settings screen shows a similar message. In addition, the Wi-Fi symbol in the status bar has a small “X” in the corner, as a hint that the network does not provide Internet access. Tapping the notification opens a browser window that usually displays the captive portal, prompting you to enter a token or simply accept some terms and conditions.
|
|
|
|
|
|
We didn’t simulate a full-blown captive portal, just returned an unexpected HTTP response code for the relevant endpoint, connectivitycheck.gstatic.com/generate<sub>204</sub>. Usually, a router would block other network traffic until the user had completed the required confirmation steps in the captive portal. In our case, all network traffic was still possible as far as the router was concerned. We used the Chrome browser to check network access to other websites. Even though the browser showed a black bar at the top saying “No Internet connection”, we were able to browse random sites just fine.
|
|
|
|
|
|
|
|
|
<a id="orgfea69a7"></a>
|
|
|
|
|
|
### 2. Manipulating DNS responses for some of Google’s domains
|
|
|
|
|
|
Setup 2) was different from the first one in that Android was unable to connect to connectivitycheck.gstatic.com/generate<sub>204</sub> and receive any HTTP response at all.
|
|
|
|
|
|
For case a), dnsmasq was configured to return a local IP address for that domain name. We knew this address was not in use at the time, so Android could not connect to an HTTP server at that address. For case b), dnsmasq was configured to return an NXDOMAIN response instead, so Android would know immediately that the address lookup had failed. For case c), iptables was configured to silently drop the relevant DNS requests.
|
|
|
|
|
|
In all three cases, Android didn’t report that the Wi-Fi connection was broken, in contrast to setup 1).
|
|
|
|
|
|
Inspecting DNS traffic on the network, we were able to observe that other domains were queried without any user interaction: google.com and www.google.com. Extending the scenarios to block these domains in addition to the connectivity check did cause Android to report that the the Wi-Fi connection was broken. The small “X” on the status bar icon appeared, the Wi-Fi settings screen showed “No Internet” for the current network, and Chrome had the additional black bar at the top saying “No Internet connection”.
|
|
|
|
|
|
Unlike setup 1), there was no prompt to sign into the network. This makes sense, as Android was not able to reach the captive portal.
|
|
|
|
|
|
As in the first setup, we used Chrome to check random websites. Except for Google, which was really blocked in this setup, we had no problems browsing the web.
|
|
|
|
|
|
|
|
|
<a id="orgf1c44aa"></a>
|
|
|
|
|
|
### Summary
|
|
|
|
|
|
When an Android device thinks that its Internet connection doesn’t work, either due to a captive portal or due to certain Google domains being unreachable, apps on the device are still able to connect to IP addresses that remain reachable, and the device can still resolve DNS queries for other domains. Even though various parts of the UI indicate that the system considers the Wi-Fi connection to be offline, the system does not seem to block any traffic as a result of this assessment.
|
|
|
|
|
|
|
|
|
<a id="org7e41f02"></a>
|
|
|
|
|
|
## Bluetooth
|
|
|
|
|
|
Bluetooth is a short-range radio technology that comes bundled with most modern day mobile devices.
|
|
|
It allows devices to discover each other, and transfer relatively small packets of data over a range of up to 33 feet.
|
|
|
The accessibility of Bluetooth API's on most modern day smartphones makes Bluetooth an attractive transport for infrastructure-free data transfers, like those needed for a public mesh system.
|
|
|
|
|
|
|
|
|
<a id="org0962a9c"></a>
|
|
|
|
|
|
### Resources
|
|
|
|
|
|
Background information about Bluetooth:
|
|
|
|
|
|
1. Bluetooth Low Energy
|
|
|
|
|
|
<https://punchthrough.com/how-gap-and-gatt-work/>
|
|
|
|
|
|
<https://www.oreilly.com/library/view/getting-started-with/9781491900550/ch04.html>
|
|
|
|
|
|
<https://github.com/weliem/blessed-android>
|
|
|
|
|
|
<https://software-dl.ti.com/lprf/simplelink_cc2640r2_sdk/1.35.00.33/exports/docs/ble5stack/ble_user_guide/html/ble-stack/l2cap.html#l2cap-connection-oriented-channel-coc-example>
|
|
|
|
|
|
<https://code.briarproject.org/briar/public-mesh-testbed/-/tree/blessed-gatt>
|
|
|
|
|
|
2. Bluetooth "classic", specifically RFCOMM
|
|
|
|
|
|
<https://developer.android.com/guide/topics/connectivity/bluetooth>
|
|
|
|
|
|
<https://code.briarproject.org/briar/public-mesh-testbed/-/tree/bt-classic>
|
|
|
|
|
|
|
|
|
<a id="org3c75e90"></a>
|
|
|
|
|
|
### BLE
|
|
|
|
|
|
Bluetooth Low Energy is a separate protocol from Bluetooth Classic that is designed to reduce the energy consumption during use, without greatly impacting functional range.
|
|
|
|
|
|
1. Security
|
|
|
|
|
|
During our research we encountered an open vulnerability which is extremely relevant to the public mesh application development space.
|
|
|
[CVE-2020-12856: A Silent Pairing Issue in Bluetooth-based Contact Tracing Apps](https://raw.githubusercontent.com/alwentiu/COVIDSafe-CVE-2020-12856/master/CVE-2020-12856-19-June-2020.pdf) by authors Alwen Tiu and Jim Mussared, released in May 2020, describes an attack which silently sends a device's Bluetooth MAC address, along with the Bluetooth Identity Resolving Key to an adversary running a spoofed BLE central. In most public mesh protocols, users publish some sort of publically-identifiable address to the network so that other users in the network can properly route intended messages to their address, so at first this does not seem like a major security issue. However, this attack is particularly relevant even in the public mesh context, because it allows for the identification of users even after a user stops utilizing the public mesh application.
|
|
|
|
|
|
1. Pairing Fix
|
|
|
|
|
|
With our BLE work on this project, we have put together a patch for the BLESSED library that we are using, which fixes this vulnerability by proxying GATT read and write values to remove the authentication flag which triggers automatic pairing. [TODO link the patch when we are eventually able to]
|
|
|
Our fix is heavily based on work by the COVIDSafe Android application team. The current version of the fix uses Java's reflection API to extract a specific field in the active \`BluetoothGatt\` object, and replace it with a proxy object that runs an \`InvocationHandler\` checking for characteristic read and write invocations.
|
|
|
The COVIDSafe files that implement this fix are:
|
|
|
|
|
|
<https://github.com/AU-COVIDSafe/mobile-android/blob/master/app/src/main/java/au/gov/health/covidsafe/streetpass/StreetPassPairingFix.kt>
|
|
|
|
|
|
<https://github.com/AU-COVIDSafe/mobile-android/blob/master/app/src/main/java/au/gov/health/covidsafe/streetpass/IBluetoothGattInvocationHandler.java>
|
|
|
|
|
|
Because we want to utilize the BLESSED library, we apply a similar patch to the underlying \`BluetoothGatt\` object that is wrapped in the \`BluetoothPeripheral\` class.
|
|
|
|
|
|
2. Existing Library
|
|
|
|
|
|
We have found that the open source Bluetooth library, [BLESSED](https://github.com/weliem/blessed-android) is useful for working with BLE on android. Their project README.md offers an introduction to the library for new users, and they also offer a number of [example projects](https://github.com/weliem/blessed-android/tree/master/app/src/main/java/com/welie/blessedexample) to help developers get started with BLESSED.
|
|
|
|
|
|
3. Android Permissions
|
|
|
|
|
|
On a mobile device, a public mesh Bluetooth service needs to be able to run uninterrupted in the background, and also need to be able to make bluetooth advertisements and connections in the background. To do this, all of the Bluetooth Low Energy based branches of the testbed application request the following permissions:
|
|
|
|
|
|
<uses-permission
|
|
|
android:name="android.permission.ACCESS_COARSE_LOCATION"
|
|
|
android:maxSdkVersion="30" />
|
|
|
<uses-permission
|
|
|
android:name="android.permission.ACCESS_FINE_LOCATION"
|
|
|
android:maxSdkVersion="30" />
|
|
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
|
|
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
|
|
<uses-permission
|
|
|
android:name="android.permission.BLUETOOTH"
|
|
|
android:maxSdkVersion="30" />
|
|
|
<uses-permission
|
|
|
android:name="android.permission.BLUETOOTH_ADMIN"
|
|
|
android:maxSdkVersion="30" />
|
|
|
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
|
|
|
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
|
|
|
<uses-permission
|
|
|
android:name="android.permission.BLUETOOTH_SCAN"
|
|
|
android:usesPermissionFlags="neverForLocation"
|
|
|
tools:targetApi="31" />
|
|
|
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
|
|
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
|
|
<uses-permission android:name="android.permission.INTERNET" />
|
|
|
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
|
|
|
|
|
On the user side, they end up getting the following permission pop-ups on API 31+ devices:
|
|
|
|
|
|
- Nearby Devices
|
|
|
- "Let app always run in the background"
|
|
|
- Notifications
|
|
|
|
|
|
On older devices, (SDK 30 and earlier) the mesh testbed app requires location-based permssions which creates a UX hurdle for future public mesh applications because it could cause users to believe their locations are being tracked.
|
|
|
|
|
|
|
|
|
<a id="org0117473"></a>
|
|
|
|
|
|
### BLESSED
|
|
|
|
|
|
1. Peer Advertisement
|
|
|
|
|
|
Peer advertisement happens using BLE's peripheral advertisement protocol. Peripheral devices build a schema of characteristics, and advertise their core service UUID over the Bluetooth frequency band.
|
|
|
Using BLESSED's library, and their \`PeripheralManager\` class, you can easily create and add characteristics:
|
|
|
|
|
|
BluetoothGattCharacteristic allocatorChar = new BluetoothGattCharacteristic(ALLOCATOR_UUID,PROPERTY_READ, PERMISSION_READ);
|
|
|
gattService.addCharacteristic(allocatorChar);
|
|
|
peripheralManager.add(gattService);
|
|
|
|
|
|
And start advertising the GATT service:
|
|
|
|
|
|
peripheralManager.startAdvertising(adSettings, adData, scanResponse);
|
|
|
|
|
|
For more information on how the \`blessed\` branch creates and advertises it's GATT service:
|
|
|
|
|
|
<https://code.briarproject.org/briar/public-mesh-testbed/-/blob/blessed-gatt/app/src/main/java/org/briarproject/publicmesh/bt/BtServiceImpl.java#L261>
|
|
|
|
|
|
2. Peer Discovery
|
|
|
|
|
|
Scanning for nearby peers is a key component of the Bluetooth Low Energy protocol. When the Bluetooth service is running, the central component of the public mesh BLE service will scan in the background looking for peripherals that are advertising the set UUID for this application. When the service discovers a nearby peripheral using the BLESSED library, it will fire the \`onDiscoveredPeripheral()\` callback function. BLESSED will also automatically handle "service discovery" which is a handshake that happens behind the scene between the devices so the central device can understand what resources are being hosted by the peripheral. BLESSED conviniently also gives you a callback on this event called \`onServicesDiscovered()\`.
|
|
|
|
|
|
3. Peer Connectivity
|
|
|
|
|
|
Bluetooth Low Energy offers two different ways of actually connecting and sharing data between devices, the previously mentioned GATT service can be used to broadcast resources that centrals can connect, and read and write to. BLE also offers L2CAP, or "logical link control and adaptation protocol". L2CAP offers a "connection oriented channel" approach that is much closer to traditional socket programming than the GATT protocol. This makes programming larger data transfers with L2CAP much easier, however API support for L2CAP on android devices is worse compared to GATT, so our general thinking is to attempt to create links between devices using L2CAP, but fall back to using GATT in case devices in the handshake do not support L2CAP.
|
|
|
|
|
|
1. GATT
|
|
|
|
|
|
Like most other BLE functionalities, BLESSED allows us to easily connect to a given \`BluetoothPeripheral\` object by using the \`centralManager.connectPeripheral()\` method. For the full implementation of peer connections on the \`blessed\` branch: <https://code.briarproject.org/briar/public-mesh-testbed/-/blob/blessed-gatt/app/src/main/java/org/briarproject/publicmesh/bt/BtServiceImpl.java#L320>
|
|
|
|
|
|
2. L2CAP
|
|
|
|
|
|
With L2CAP, there is less of a divide between "central" and "peripheral" devices like in the GATT system. Instead of advertising a set of resources like a GATT peripheral device, with L2CAP, devices advertise a "PSM" value which is similar to a port number, and open a Bluetooth Server Socket running on that PSM value. On our \`blessed\` branch, we advertise the open socket if the device supports L2CAP:
|
|
|
|
|
|
if (USE_L2CAP && SDK_INT >= 29 && serverSocket == null) openServerSocket();
|
|
|
AdvertiseSettings adSettings = new AdvertiseSettings.Builder()
|
|
|
.setConnectable(true)
|
|
|
.setTimeout(0)
|
|
|
.build();
|
|
|
AdvertiseData adData = new AdvertiseData.Builder().addServiceUuid(PARCEL_UUID).build();
|
|
|
AdvertiseData scanResponse;
|
|
|
if (USE_L2CAP && SDK_INT >= 29) {
|
|
|
byte[] serviceData = new byte[4];
|
|
|
writeUint32(psm, serviceData, 0);
|
|
|
scanResponse = new AdvertiseData.Builder()
|
|
|
.addServiceData(PARCEL_UUID, serviceData)
|
|
|
.build();
|
|
|
}
|
|
|
|
|
|
Then, whenever we discover a L2CAP-compatible device, we can connect to it using a method like the \`connectViaSocket()\` method on the \`blessed\` branch: <https://code.briarproject.org/briar/public-mesh-testbed/-/blob/blessed-gatt/app/src/main/java/org/briarproject/publicmesh/bt/BtServiceImpl.java#L416>
|
|
|
|
|
|
4. Notes
|
|
|
|
|
|
- Some devices (eg Samsung J5 2016) receive the advertising packet but not the scan record, so if we want to provide extra information in the scan record we also need to make this information available via GATT
|
|
|
- BLESSED doesn't provide a wrapper for the new advertising set API, which supports new Bluetooth 5 advertising features such as periodic advertising, extended advertising and coded PHY, so if we want to use those features we'll need to use the Android API directly
|
|
|
- If we use any Bluetooth 5 advertising features then we also need to use the Android API for scanning (or submit a pull request upstream to allow legacy mode to be turned off for scanning)
|
|
|
- We can, however, use BLESSED to request coded PHY for GATT connections
|
|
|
- BLESSED also makes it relatively painless to send and receive information via GATT characteristics
|
|
|
- Some devices allow connections to multiple peripherals when acting as a central
|
|
|
- Some devices also support connections from multiple centrals when acting as a peripheral, but since GATT doesn't provide a way to send data to a specific central we'd need to do some creative thinking to make use of this
|
|
|
- L2CAP connection-oriented channels (CoC) seem to work as advertised. The server socket provides a PSM (something like a dynamic port number) that needs to be communicated to the client somehow (eg via BLE advertising). We can use L2CAP when the central and peripheral both support it and fall back to GATT when they don't
|
|
|
- The P8 Lite doesn't support advertising (BluetoothAdapter#getBluetoothLeAdvertiser() returns null)
|
|
|
- The Moto G never receives the result of starting advertising (no callback to onAdvertisingStarted() or onAdvertiseFailure())
|
|
|
- The Moto G and P8 Lite can discover the J5, but it can't discover them and they can't discover each other
|
|
|
- The P8 Lite can connect to the J5 via GATT and exchange pings and pongs
|
|
|
- The Moto G can't connect to the J5 via GATT: it receives a callback to onConnectingPeripheral(), never receives onConnectedPeripheral(), and eventually receives onDisconnectedPeripheral() with status LMP<sub>OR</sub><sub>LL</sub><sub>RESPONSE</sub><sub>TIMEOUT</sub>. The J5 receives onCentralConnected() and onCentralDisconnected() as expected. The J5 can subsequently connect back to the Moto G, using the address it learned from the unsuccessful connection, and exchange pings and pongs
|
|
|
- When the J5 receives a connection from the Moto G or P8 Lite, the J5 sees the same address that the Moto G/P8 Lite gets from its own BluetoothAdapter, ie the BT classic address. So it may be possible for the Moto G/P8 Lite to advertise this address via WFD (since BLE advertising isn't available) and use the address to receive GATT connections and/or BT classic connections.
|
|
|
|
|
|
|
|
|
<a id="org4b874c2"></a>
|
|
|
|
|
|
### BLE Allocator Characteristic
|
|
|
|
|
|
The \`blessed\` testbed branch exemplifies how individual connections can be made using BLE. However, the one of the core features for a performant ad-hoc mesh system is the ability to make simultanious p2p connections between 3+ devices. In order to support multi-device scenarios, we developed the "allocator characteristic" system which guides incoming central devices to the correct read characteristic, in order to read arbitrary amounts of data from the advertising peripheral device.
|
|
|
The high level structure of the allocator characteristic system is built using two main characteristics:
|
|
|
|
|
|
- Read Characteristic
|
|
|
|
|
|
This is a characteristic that a single central will connect to and read data from.
|
|
|
At Bluetooth service startup the number of read characteristics is known so for each device there is an upper limit to the amount of simultaneous central connections.
|
|
|
|
|
|
- Allocator Characteristic
|
|
|
|
|
|
The allocator characteristic is a readable characteristic that displays a list of SESSION<sub>ID</sub>'s of connected devices.
|
|
|
When a new central tries to make a connection to the peripheral device, it will first check this list to confirm it is not already currently reading from that peripheral device.
|
|
|
This system also allows centrals to monitor when a peripheral is fully busy with devices reading from it.
|
|
|
|
|
|
1. Peer Advertisement
|
|
|
|
|
|
Peer advertisement is nearly identical to the previous BLESSED section, the Bluetooth peripheral service will advertise a characteristic with a dedicated UUID representing the public mesh application.
|
|
|
|
|
|
2. Peer Discovery
|
|
|
|
|
|
At its core, peer discovery is similar to the approach listed in the BLESSED section earlier. A central Bluetooth device scans for the UUID for the appropriate characteristic. However, with the added allocator characteristic, there is another method that peers can find each other. The allocator characteristic works as an active list of nearby peers, so higher level protocols could possibly utilize this as a way to further increase peer discovery and data propagation.
|
|
|
|
|
|
3. Peer Connectivity
|
|
|
|
|
|
Because each peripheral has a limited number of read characteristics, protocols built on top of this strategy should prioritize quicker, more frequent connections rather than long lasting data transfers.
|
|
|
A central connects to a peripheral by first by reading the peripheral's allocator characteristic, and confirming it is not already reading from that peripheral. On the connection, the central gives the peripheral it's SESSION<sub>ID</sub>, which is then added to the peripheral's allocator characteristic. By reading this update, the central receives information on which read characteristic to read from. The full handshake as implemented in \`blessed-gatt-allocator-vuln\` and \`blessed-gatt-allocator-pairfix\` is outlined below:
|
|
|
[TODO allocator diagram]
|
|
|
|
|
|
It can be noted that this has been a GATT-only protocol so far, the reasoning behind this is that GATT has much greater support among Android devices, especially devices running older hardware. This allocator system allows for an L2CAP-like abstraction to be made on top of regular GATT reads and writes, and this abstraction could also suport L2CAP (and potentially other transport layers like Local Service Discovery) under the hood for devices that support it.
|
|
|
|
|
|
4. Notes
|
|
|
|
|
|
|
|
|
<a id="org970e8d5"></a>
|
|
|
|
|
|
### BluetoothCommunicator
|
|
|
|
|
|
BluetoothCommunicator is a BLE library built upon the core Android \`BluetoothGATT\` objects similar to BLESSED. However, unlike BLESSED, BluetoothCommunicator is geared more towards async messaging, and not a general-use library. Because of the added flexibility working with BLESSED gives us, future development of BLE mesh networking tools will likely focus on our allocator characteristic framework. However it is useful to research the BluetoothCommunicator library because it gives us insight into how a higher-level messaging framework might be built upon the allocator characteristic system.
|
|
|
|
|
|
1. Peer Advertisement
|
|
|
|
|
|
TODO find code snippets from blechat impl
|
|
|
|
|
|
2. Peer Discovery
|
|
|
|
|
|
3. Peer Connectivity
|
|
|
|
|
|
4. Notes
|
|
|
|
|
|
While the library has methods built to enable autopeering, our attempt to enable autopeering with this framework proved unsuccessful.
|
|
|
|
|
|
|
|
|
<a id="org18dfbcb"></a>
|
|
|
|
|
|
## WiFi
|
|
|
|
|
|
|
|
|
<a id="orge1b6347"></a>
|
|
|
|
|
|
### Network Service Discovery (NSD)
|
|
|
|
|
|
1. Peer Advertisement
|
|
|
|
|
|
<https://developer.android.com/training/connect-devices-wirelessly/nsd#register>
|
|
|
|
|
|
2. Peer Discovery
|
|
|
|
|
|
<https://developer.android.com/training/connect-devices-wirelessly/nsd#discover>
|
|
|
|
|
|
3. Peer Connectivity
|
|
|
|
|
|
<https://developer.android.com/training/connect-devices-wirelessly/nsd#connect>
|
|
|
|
|
|
4. Notes
|
|
|
|
|
|
- It's probably worth noting that NSD is also a special case for Android apps running on ChromeOS: apps can't generally make or receive connections via the LAN, except in the case of outgoing connections to services discovered via NSD. See [briar#1362](https://code.briarproject.org/briar/briar/-/issues/1362).
|
|
|
- This comment suggests that NSD service resolution will fail for network interfaces that don't have an associated Network instance:
|
|
|
|
|
|
<https://cs.android.com/android/platform/superproject/+/master:packages/modules/Connectivity/service-t/src/com/android/server/NsdService.java;drc=b45a2ea782074944f79fc388df20b06e01f265f7;l=576>
|
|
|
|
|
|
- On at least some devices, NSD works when using a WFD legacy mode hotspot. Tested with Samsung A21s as hotspot, Nokia 1.3 as client and vice versa. Tested with the \`wifi-direct-and-nsd\` branch.
|
|
|
|
|
|
- When discovering services via NSD, one needs to resolve each service found to find out IP address, port etc.
|
|
|
|
|
|
NsdManager has a method resolveService() for this. Only one service can be resolved at a time, an error with code FAILURE<sub>ALREADY</sub><sub>ACTIVE</sub> will appear when a second simultaneous resolve request is submitted. Hence it is important not to call that method right away when new services have been discovered, instead a queue needs to be maintained and worked on one by one. Resolving a service can succeed or fail and after both events, it should be possible to resolve the next service. It seems however, that sometimes resolving neither succeeds nor fails, but instead we receive a service lost event. We don't get any updates on the resolving request afterwards, but we also cannot submit a new resolve request afterwards, they will still fail with a FAILURE<sub>ALREADY</sub><sub>ACTIVE</sub> error. Even restarting the service discovery entirely did not seem to help.
|
|
|
|
|
|
- The \`lan-service-discovery-nsd-no-resolution\` branch encodes the IP address in the NSD service name, allowing us to skip the buggy resolution step.
|
|
|
|
|
|
This means we can't advertise attributes, unless we encode them in the service name along with the address or fetch them separately via unicast. This (abandoned) library implements the latter approach to work around the empty attributes map issue mentioned above:
|
|
|
<https://github.com/youviewtv/tinydnssd>
|
|
|
Alternatively we could implement our own unicast protocol for fetching attributes, while still using NSD for the multicast part, to benefit from the special treatment it seems to get on some devices.
|
|
|
|
|
|
|
|
|
<a id="org7e86006"></a>
|
|
|
|
|
|
### Local Service Discovery (LSD)
|
|
|
|
|
|
"Local Service Discovery (LSD) provides a SSDP-like (http over udp-multicast) mechanism to announce the presence in specific swarms to local neighbors. It can be used either as primary peer source for local transfers or to complement other sources which only operate on global unicast addresses." - [bep<sub>0014</sub>](https://www.bittorrent.org/beps/bep_0014.html)
|
|
|
|
|
|
1. Peer Advertisement
|
|
|
|
|
|
<https://www.bittorrent.org/beps/bep_0014.html#protocol>
|
|
|
|
|
|
The protocol could be further modified for this purpose by removing the infohash and (optional) cookie field. This comes at the effect of giving your application a more noticeable "fingerprint".
|
|
|
|
|
|
2. Peer Discovery
|
|
|
|
|
|
To discover peers on the network, start a UdpClient at the specified addresses: A) 239.192.152.143:6771 (org-local) and B) [ff15::efc0:988f]:6771 (site-local)
|
|
|
|
|
|
3. Peer Connectivity
|
|
|
|
|
|
Once peers are discovered, a normal TCP connection can be made with the \`HOST:PORT\` value shared in the announcement packet.
|
|
|
|
|
|
4. Notes
|
|
|
|
|
|
|
|
|
<a id="org38f6c2d"></a>
|
|
|
|
|
|
### WiFi Client
|
|
|
|
|
|
1. Peer Advertisement
|
|
|
|
|
|
2. Peer Discovery
|
|
|
|
|
|
3. Peer Connectivity
|
|
|
|
|
|
4. Notes
|
|
|
|
|
|
The \`wifi-client-request-network\` branch uses three different techniques for requesting a connection to a specific wifi network:
|
|
|
|
|
|
1. API >= 29 (tested on Samsung A21s and Nokia 1.3): The app uses WifiNetworkSpecifier, as recommended here. When the app requests the network, the system shows a progress indicator and searches for the network nearby. If the network isn't found, the system shows a dialog with options to try again or cancel. If the network is found, the system shows a dialog asking the user whether to connect or cancel. The app receives a callback with the user's response. The requested network does not appear in the device's list of saved networks. If the device is already connected to a wifi network with internet access, it disconnects and connects to the requested network instead. As expected, there is no warning about lack of internet access and the device stays connected to the network. The app can disconnect from the requested network by unregistering the NetworkCallback. After doing this, reconnecting to the requested network requires confirmation from the user again. The docs seem to suggest that if the app doesn't unregister the callback then the app can reconnect to the requested network in future without needing user approval again, but I haven't tested this yet.
|
|
|
2. API < 29 (tested on Nexus 5X): The app creates a WifiConfiguration with a high priority value, adds the configuration via WifiManager#addNetwork(), and enables the configuration via WifiManager#enableNetwork(). This doesn't require user approval and connects to the requested network immediately, even if the device is currently connected to a network with internet access and the requested network doesn't have internet access. The requested network is added to the device's list of saved networks. There is no warning about lack of internet access and the device stays connected to the network. The app can disconnect from the requested network and remove the saved configuration by calling WifiManager#removeNetwork().
|
|
|
3. API < 29 (tested on Nexus 5X): As in the previous method, the app creates a WifiConfiguration with a high priority value and adds the configuration via WifiManager#addNetwork(). The app then uses reflection to call WifiManager#connect(). Like the previous method, this connects to the requested network immediately, even if the device is currently connected to a network with internet access and the requested network does not have internet access. The requested network is added to the device's list of saved networks. There is no warning about lack of internet access and the device stays connected to the network. The app can disconnect from the requested network and remove the saved configuration by calling WifiManager#removeNetwork().
|
|
|
|
|
|
|
|
|
<a id="orga6da152"></a>
|
|
|
|
|
|
### WiFi Direct
|
|
|
|
|
|
1. Peer Advertisement
|
|
|
|
|
|
2. Peer Discovery
|
|
|
|
|
|
3. Peer Connectivity
|
|
|
|
|
|
4. Notes
|
|
|
|
|
|
|
|
|
<a id="org7efd1ad"></a>
|
|
|
|
|
|
## Alternative Transports
|
|
|
|
|
|
1. OuiSync
|
|
|
|
|
|
It is currently possible to route Briar one-on-one messages using a Ouisync repo by using the file export function. This idea could be further explored by building processes in Briar to more easily export large amounts of messages, or even automate the import and export of encrypted files.
|
|
|
|
|
|
2. P2P Connections over Intranets
|
|
|
|
|
|
One existing question related to Ouisync and other alternative networking tools is how they perform in situations where there is a national-level intranet, and two peers both inside the intranet want to connect. If reliable ways to make p2p intranet connections are found, it could be an interesting transport layer for Briar or a similar app to implement.
|
|
|
|
|
|
3. LoRa / Ham Radio
|
|
|
|
|
|
TODO
|
|
|
|
|
|
4. Filesystem API
|
|
|
|
|
|
|
|
|
<a id="org12ba11d"></a>
|
|
|
|
|
|
## Future Considerations
|
|
|
|
|
|
|
|
|
<a id="org2e599ad"></a>
|
|
|
|
|
|
### Mix-and-Match Transport Layers
|
|
|
|
|
|
Out of the transport layers covered in this report, each transport layer has it's own trade-offs. By combining transport layers in interesting ways, we can create higher networking abstractions that could possibly offer better performance than each individual transport layer on it's own. One immediate example of this is using Bluetooth to advertise WiFi identifiers to bootstrap LSD connections. Doing large file transfers over LAN is much preferred to doing it over Bluetooth, so this approach could lead to better performance in situations where one peer is connected to a WiFi network that a nearby peer could also connect to.
|
|
|
|
|
|
|
|
|
<a id="org06644e6"></a>
|
|
|
|
|
|
### Evaluate Briar's Threat Model
|
|
|
|
|
|
|
|
|
<a id="orge2804d6"></a>
|
|
|
|
|
|
### Transport Energy Draw Experiments
|
|
|
|
|
|
1. Outline
|
|
|
|
|
|
|
|
|
<a id="org8e12274"></a>
|
|
|
|
|
|
# Routing Protocols [WIP]
|
|
|
|
|
|
|
|
|
<a id="orgd01fde7"></a>
|
|
|
|
|
|
## Existing Research
|
|
|
|
|
|
|
|
|
<a id="orgd77c49e"></a>
|
|
|
|
|
|
# UI/UX Research [WIP]
|
|
|
|
|
|
|
|
|
<a id="org63e0a5d"></a>
|
|
|
|
|
|
## Security Profiles
|
|
|
|
|
|
TODO insert tor screenshots
|
|
|
|
|
|
|
|
|
<a id="orgcec3fe9"></a>
|
|
|
|
|
|
## Connectivity Profiles
|
|
|
|
|
|
TODO insert figma designs
|
|
|
|
|
|
|
|
|
<a id="org65e3ac0"></a>
|
|
|
|
|
|
# Appendix
|
|
|
|
|
|
|
|
|
<a id="org3415686"></a>
|
|
|
|
|
|
## Similar Projects
|
|
|
|
|
|
|
|
|
<a id="org69796f3"></a>
|
|
|
|
|
|
### Community and mesh networks:
|
|
|
|
|
|
<http://consume.net/> and <https://dek.spc.org/julian/consume/>
|
|
|
<https://wirelessleiden.nl/en> and <https://wirelessleiden.nl/en/news/2022/02/wifi-network-will-be-phased-out>
|
|
|
<https://villagetelco.org/> and <https://villagetelco.org/mesh-potato/>
|
|
|
<https://forum.xda-developers.com/t/piratebox-mobile-paw-intergrated.935157/>
|
|
|
<http://guifi.net/en>
|
|
|
<https://wiki.hacdc.org/index.php?title=Category:Byzantium> and <https://github.com/Byzantium/Byzantium/wiki>
|
|
|
<https://dn42.eu/Home>
|
|
|
<https://sudoroom.org/wiki/Mesh>
|
|
|
<http://www.mazizone.eu/>
|
|
|
<https://netcommons.eu/>
|
|
|
<https://www.lantern.works/>
|
|
|
<https://disaster.radio/> and <https://github.com/sudomesh/disaster-radio/wiki>
|
|
|
<https://developer.synapse-wireless.com/getting-started/index.html>
|
|
|
<http://subnodes.org/>
|
|
|
<https://gitlab.epfl.ch/sacs/ssb/smallworld/gossiping-locally>
|
|
|
<https://mallaveinal.net/>
|
|
|
<https://www.apc.org/en/blog/seeding-change-creating-digital-community-network-juhoan-people-namibia>
|
|
|
<https://www.rhizomatica.org/>
|
|
|
<https://tylercipriani.com/blog/2022/07/31/meshtastic-a-review/>
|
|
|
<https://en.wikipedia.org/wiki/Optimized_Link_State_Routing_Protocol>
|
|
|
<http://www.olsr.org/docs/README-Link-Quality.html>
|
|
|
<https://www.open-mesh.org/projects/open-mesh/wiki>
|
|
|
<https://www.irif.fr/~jch//software/babel/>
|
|
|
<https://openmesh.wordpress.com/2011/01/30/a-list-of-open-source-ad-hoc-network-and-routing-protocolsplatforms/>
|
|
|
<https://code.google.com/archive/p/adhoc-on-android/>
|
|
|
<https://github.com/thinktube-kobe/airtube/wiki>
|
|
|
<http://www.broadband-hamnet.org/>
|
|
|
<http://clusterduckprotocol.org/>
|
|
|
<https://www.project-owl.com/>
|
|
|
<https://unsigned.io/reticulum-overview/> and <https://github.com/markqvist/Reticulum> and <https://markqvist.github.io/Reticulum/manual/> and <https://github.com/markqvist/Sideband>
|
|
|
<https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/esp-wifi-mesh.html>
|
|
|
<https://unsigned.io/projects/rnode/>
|
|
|
<https://rfc.zeromq.org/spec/36/>
|
|
|
<https://blaubot.henning-gross.de/>
|
|
|
<https://qaul.net> and <https://qaul.github.io/qaul.net/#/qaul/README>
|
|
|
|
|
|
|
|
|
<a id="orgcb9e9e6"></a>
|
|
|
|
|
|
### Darknet and friend-to-friend projects:
|
|
|
|
|
|
<https://sourceforge.net/projects/alliancep2p/>
|
|
|
<https://code.google.com/archive/p/anonshare/>
|
|
|
<https://code.google.com/archive/p/antagonist/>
|
|
|
<https://cryptic6.sourceforge.net/>
|
|
|
<https://easta.sourceforge.net/>
|
|
|
<https://galet.sourceforge.net/>
|
|
|
<https://hybrid-share.sourceforge.net/>
|
|
|
<https://learn.microsoft.com/en-us/openspecs/office_protocols/ms-grvprot/a4ff425f-5023-4053-ba03-d0870a06eca9>
|
|
|
<https://www.powerfolder.com/>
|
|
|
<http://retroshare.cc/index.html>
|
|
|
<https://waste.sourceforge.net/> and <http://wastekeyexchange.blogspot.com/> and <https://wasteagain.sourceforge.net/introduction.shtml> and <https://sourceforge.net/projects/swarmdarknet/>
|
|
|
<https://www.ntop.org/products/n2n/>
|
|
|
<https://gobby.github.io/>
|
|
|
<http://sneer.me/>
|
|
|
<https://teapotnet.org/>
|
|
|
|
|
|
|
|
|
<a id="orge011c69"></a>
|
|
|
|
|
|
### Social P2P projects:
|
|
|
|
|
|
<https://www.gigatribe.com/en/>
|
|
|
<http://kerjodando.blogspot.com/>
|
|
|
<https://www.tribler.org/>
|
|
|
<http://incliq.com/>
|
|
|
<https://github.com/mnaamani/otrtalk>
|
|
|
<https://secushare.org/>
|
|
|
<https://getaether.net/>
|
|
|
<https://github.com/coronanet>
|
|
|
<https://cblgh.org/trustnet/>
|
|
|
<https://cabal.chat/>
|
|
|
<https://radicle.xyz/>
|
|
|
<https://openprivacy.ca/discreet-log/13-metadata-resistant-filesharing/>
|
|
|
<https://github.com/jeremyckahn/chitchatter>
|
|
|
<https://github.com/sebkur/lanchat>
|
|
|
|
|
|
|
|
|
<a id="org58cb9af"></a>
|
|
|
|
|
|
### Sneakernets and DTN:
|
|
|
|
|
|
<https://github.com/drewcrawford/sneakernet>
|
|
|
<https://code.google.com/archive/p/sneakernet/>
|
|
|
<http://k0a1a.net/netless/>
|
|
|
<https://github.com/blanu/sneakermesh>
|
|
|
<https://www.watershed.co.uk/studio/node/887/> and <https://github.com/Tim-Kindberg/crowdnet>
|
|
|
<https://datatracker.ietf.org/doc/html/rfc4838> and <https://datatracker.ietf.org/doc/html/rfc5050> and <https://www.rfc-editor.org/rfc/rfc5325> and <https://datatracker.ietf.org/doc/html/rfc9171> and <https://datatracker.ietf.org/doc/html/rfc9172>
|
|
|
<https://github.com/Mobisocial/dungbeetle>
|
|
|
<https://github.com/endymion/sneakernet>
|
|
|
<https://github.com/megamattron/SplinterNet>
|
|
|
<https://code.google.com/archive/p/twimight/>
|
|
|
<https://www.androidpolice.com/2014/10/31/googles-copresence-api/>
|
|
|
<http://thaliproject.org/ExperimentWithFireChat/>
|
|
|
<https://github.com/zeromq/zyre>
|
|
|
<https://internet-in-a-box.org/>
|
|
|
<https://github.com/ole-old/BeLL-System-Documentation>
|
|
|
<http://wiki.sugarlabs.org/go/Platform_Team/Sugar_Network/Architecture>
|
|
|
<https://github.com/Muterra/doc-golix>
|
|
|
<https://github.com/casific/murmur>
|
|
|
<https://github.com/chrisballinger/BLEMeshChat>
|
|
|
<https://offlinefirst.org/>
|
|
|
<https://github.com/Nutomic/ensichat>
|
|
|
<https://github.com/thaliproject> and <https://www.goland.org/thalimesh/> and <http://thaliproject.org/AndroidP2P/>
|
|
|
<http://www.nncpgo.org/> and <https://changelog.complete.org/archives/10421-dead-usb-drives-are-fine-building-a-reliable-sneakernet>
|
|
|
<https://github.com/guardianproject/WindChime-Android>
|
|
|
<https://github.com/lulzlabs/AirChat>
|
|
|
<https://baydet.medium.com/dark-corners-of-multipeer-connectivity-framework-abd566422920>
|
|
|
<https://github.com/ssbc> and <https://handbook.scuttlebutt.nz/> and <https://ssbc.github.io/scuttlebutt-protocol-guide/> and <https://scuttlebot.io/> and <https://www.manyver.se/>
|
|
|
<https://getaura.io/>
|
|
|
<https://github.com/bantucracy/ayanda>
|
|
|
<https://docs.ditto.live/>
|
|
|
<https://bridgefy.me/> and <https://bridgefy.me/docs/javadoc/> and <https://github.com/bridgefy/bridgefy-android-sdk-sample> and <https://eikendev.github.io/breaking-bridgefy-again/>
|
|
|
<https://awala.network/>
|
|
|
<https://github.com/Hariharan-Gandhi/WiFriends>
|
|
|
<https://www.usenix.org/legacy/events/hotsec10/tech/techAbstracts.html#Aviv> and <https://www.cs.swarthmore.edu/~aviv/papers/aviv-priv_humanets.pdf>
|
|
|
<https://dtn7.github.io/> and <https://github.com/RightMesh/Terra/> and <https://github.com/NodleCode/dtn7-kotlin/>
|
|
|
<https://www.netlab.tkk.fi/~jo/papers/2014-04-wons-liberouter.pdf> and <http://liberouter.mobi/> and <https://blog.apnic.net/2018/12/18/librerouter-powering-community-networks-with-free-and-open-hardware/> and <https://research.aalto.fi/en/publications/opportunistic-networking-applications-from-theory-to-practice>
|
|
|
<http://www.servalproject.org/> |