DevelopersP2pLocal Network Discovery
P2p

Local Network Discovery

Implementation

Our local network discovery uses DNS-Based Service Discovery which itself is built around Multicast DNS (mDNS). This is a really well established technology and is used in Spotify Connect, Apple Airplay and many other services you use every day.

We make use of the mdns-sd crate.

Service Structure

The following is an example of what would be broadcast from a single Spacedrive node:

# {remote_identity_of_self}._sd._udp.local.

name=Oscars Laptop        # Shown to the user to select a device
operating_system=macos    # Used for UI purposes
device_model=MacBook Pro  # Used for UI purposes
version=0.0.1 						# Spacedrive version

# For each library that's active on the Spacedrive node:
# {library_uuid}={remote_identity_of_self}
d66ed0c3-03ac-4f9b-a374-a927830dfd5b=0l9vTOWu+5aJs0cyWxdfJEGtloEepGRAXcEuDeTDRPk

Within sd-core this is defined in two parts. The PeerMetadata struct takes care of the node metadata and libraries are inserted by the libraries_hook.

Modes

note

This section discusses 'Contacts Only' which is not yet fully implemented (refer to ENG-1197).

Within Spacedrive's settings the user is able to choose between three modes for local network discovery:

  • Contacts only: Only devices that are in your contacts list will be able to see your device.
  • Enabled: All devices on the local network will be able to see your device.
  • Disabled: No devices on the local network will be able to see your device.

Enabled and Disabled are implemented by spawning and shutting down the sd_p2p::Mdns service as required within sd-core.

Contacts only the mDNS service will not contain the PeerMetadata fields and instead will contain a hash of the users Spacedrive identifier. If a Spacedrive node detects another node in the local network with a hash in it's contacts, it can make a request to the node and if the remote node also has the current node in it's contacts, it will respond with the full metadata.

Integration with Spacedrive accounts

P2P is currently not integrated with Spacedrive accounts and we will integrate it in the future for better security.

Right now we use a remote identity to identify the remote device, however tihs is not very user friendly. If a MITM-style attack is preformed the remote identity will show up with the attacker's device but this isn't going to be particularly noticable by the user.

To combat this issue we can integrate with Spacedrive accounts so the user can be presented with the users name and verified email. This allows the user to prove the remote device is who they expect in a more user friendly way.

The Spacedrive account information will need to be put into the peer metadata and we can use cryptographic signatures to verify the account is linked with the remote device without a network connection.

This issue is tracked as ENG-1758

Problems with Docker

Docker can be problematic with P2P due to it applying another level of NAT. This shouldn't cause any issues for usage with the relay but it makes mDNS cease to work.

It is possible to expose the mDNS daemon of the host machine into the container, and we could potentially implement something similar, however it's unclear if mdns-sd uses the OS's daemon and if avahi is used by all host Linux distributions we want to support.

When sd-server is run from Docker the Dockerfile sets the environment variable SD_DOCKER=true which is picked up by the core and it exposes P2P on port 7373 instead of a random port like the default configuration.

This allows the administrator to use the -p 7373:7373 flag when running the container to expose the P2P port to the host machine. This can then be paired with manually entering the IP address and port of the node into the P2P settings of the other node and a connection can be established. Although this is suboptimal, it serves as an alternative for the time being.

This issue is tracked as ENG-1343.

Problems with mobile

mDNS discovery does not work on mobile at the moment. To prevent this affecting other devices, we patch if-watch using the fork spacedriveapp/if-watch. This fork basically implements a no-op for mobile so that the core is able to compile.

This issue is tracked as ENG-1108.

Problems on Linux

It was reported on Discord that opening Spacedrive would cause excessive network activity. This is possibly a bug with the mDNS system; it was not able to be reproduced on macOS.

This issue is tracked as ENG-1319.

Tracking

When information about the device is exposed to the local network we introduce the risk that this information is used for tracking users.

The intention is for the contacts only mode to mitigate this risk as the device will only be discoverable by other devices that are in the users contacts and all information will be unintelligible.

Apple outline some information about how they combat this for AirDrop here and we can do something similar.