More More P2P Docs (#2525)

* Docs

* Clarify relay upgrades

* caaaaalapse

* Cleanup `sd_p2p_tunnel`
This commit is contained in:
Oscar Beaumont
2024-05-31 15:51:59 +08:00
committed by GitHub
parent 735e80ad4d
commit 58dd5c5d3e
12 changed files with 274 additions and 200 deletions

View File

@@ -50,16 +50,30 @@ From my ([oscartbeaumont](https://github.com/oscartbeaumont)'s) perspective this
## Sync
Unimplemented
[Implementation](https://github.com/spacedriveapp/spacedrive/blob/main/core/src/p2p/sync/mod.rs)
In an earlier version of the P2P system we had a method for sending sync messages to other nodes over the peer to peer connection, however this was removed during some refactoring of the sync system.
This protocol takes care of sending sync messages between nodes. This is an alternative to the Cloud-based system.
The code for it could be taken from [here](https://github.com/spacedriveapp/spacedrive/blob/aa72c083c2e5f6cf33f3c1fb66283e5fe0d1ba3b/core/src/p2p/pairing/mod.rs) and upgraded to account for changes to the sync and P2P system to bring back this functionality.
This protocol uses [`sd_p2p_tunnel::Tunnel`](/docs/developers/p2p/sd_p2p_tunnel) so ensure the recipient is paired into the library.
## Loading remote files
## Loading thumbnails and files remotely
TODO - Loading file within location over P2P
[Implementation](https://github.com/spacedriveapp/spacedrive/blob/main/core/src/p2p/operations/library.rs)
This protocol takes care of loading both thumbnails and files remotely. This is used when the media is not available on the local mode.
This protocol transparently extends the custom URI protocol and uses information in the database to determine the node responsible for the file.
This protocol uses [`sd_p2p_tunnel::Tunnel`](/docs/developers/p2p/sd_p2p_tunnel) so ensure the recipient is paired into the library.
### Design issues
Right now the system relies on the `instance_id` column on the `Location` to table to determine which node to route the media request to. This is a suboptimal solution as a location may move nodes, a good example of this is a USB drive.
A better design would be to have an in-memory table of `HashMap<LocationId, NodeRemoteIdentity>` and then using another P2P protocol which sends a message to all connected nodes when a location comes online/offline on the current node.
## Sync preview media
https://linear.app/spacedriveapp/issue/ENG-910/sync-preview-media
Unimplemented
Tracked by [ENG-910](https://linear.app/spacedriveapp/issue/ENG-910/sync-preview-media)

View File

@@ -31,6 +31,10 @@ Currently we connect to every relay server that is returned from the discovery s
The issue of connecting to every relay server is tracked as [ENG-1672](https://linear.app/spacedriveapp/issue/ENG-1672/mesh-relays).
## Connection upgrades
The relay will attempt to upgrade the connection between any peers to a direct connection if possible. If the firewall conditions are too challenging the relay will proxy the encrypted traffic between the two peers as a fallback.
## Authentication
Currently the relay service is completly unauthenticated. To prevent abuse we are planning to restrict the relays to Spacedrive accounts.

View File

@@ -7,21 +7,51 @@ index: 24
[Implementation](https://github.com/spacedriveapp/spacedrive/tree/main/crates/p2p/crates/block)
A file block protocol based on [SyncThing Block Exchange Protocol v1](https://docs.syncthing.net/specs/bep-v1.html).
This crate contains utilities focused on moving large arrays of bytes (files) between two peers reliabily and quickly. It's implementation is heavily inspired by [SyncThing Block Exchange Protocol v1](https://docs.syncthing.net/specs/bep-v1.html).
The goal of this protocol is to take bytes in and reliabily and quickly transfer them to the other side.
## Rewrite?
[Tracking issue](https://linear.app/spacedriveapp/issue/ENG-1760/block-protocol-v2)
The current implementation is a bit of a mess and is definitely not as performant as it could be. A rewrite is probally a good idea to improve it and as it is a small component of the overall networking system it should be a fairly easy undertaking.
Below I have outlined some of my thoughts on how to build an improved version:
### Progress tracking
Currently the protocol works like the following:
- Send block of file
- Wait for ack
- Send next block
This is obviously not ideal as it means the sender is waiting for the receiver to ack each block before sending the next one.
I originally added this to combat the fact that the progress indicator's were not the same on both sides, however I don't think this was worth the trade off. I was also generally testing on the same machine at this stage so it's entirely possible in the real world the progress is actually close enough without requiring acknowledgements.
We can either, remove acknowledgements or send them less frequently, some testing would be required to determine the best approach.
### Integrity checking
[Tracking issue](https://linear.app/spacedriveapp/issue/ENG-1312/spaceblock-file-checksum)
I think the new version of the protocol should compute a [Blake3](https://en.wikipedia.org/wiki/BLAKE_(hash_function)) hash on both the sender and the receiver and ensure they much before the transfer is considered complete. This ensures both any data corruption or bugs in the Spacedrop protocol don't result in data loss for the user. The current protocol lacks this feature.
### Cancellation
Currently the protocol has a custom system built into the acknowledgements that allows each side to cancel an in-progress transfer. A more efficent system could just close the Quic connection and rely on an [`ErrorKind::UnexpectedEof`](https://doc.rust-lang.org/stable/std/io/enum.ErrorKind.html#variant.UnexpectedEof) on the other side to detect the shutdown condition.
### Remove file names
[Tracking issue](https://linear.app/spacedriveapp/issue/ENG-1292/spaceblock-abstract-name-from-spaceblockrequest)
It doesn't make a lot of sense for `SpaceblockRequests` to have the `name` field as you may send an unnamed buffer. Where it should go instead is still undecided.
### File name overflows
[Tracking issue](https://linear.app/spacedriveapp/issue/ENG-572/spaceblock-file-name-overflow)
Right now it's possible for a file name's length to overflow. Linux allows for bigger file names than Windows so a transfer from Linux to Windows with a long file name will cause an issue on the Windows side. We can probally prompt the user to pick a shorter name if we detect an overflow.
## Example
```rust
# TODO
```
TODO - Outline my idea for a better implementation.
https://linear.app/spacedriveapp/issue/ENG-1760/block-protocol-v2
https://linear.app/spacedriveapp/issue/ENG-1292/spaceblock-abstract-name-from-spaceblockrequest
https://linear.app/spacedriveapp/issue/ENG-1312/spaceblock-file-checksum
https://linear.app/spacedriveapp/issue/ENG-563/spaceblock-error-handling
https://linear.app/spacedriveapp/issue/ENG-567/spaceblock-cancel-transfer
https://linear.app/spacedriveapp/issue/ENG-572/spaceblock-file-name-overflow
Refer to [the tests](https://github.com/spacedriveapp/spacedrive/blob/0392c781d75d8f8a571ed43a61ce90e11c7d73d5/crates/p2p/crates/block/src/lib.rs#L227) to see an example of how to use the protocol.

View File

@@ -7,12 +7,18 @@ index: 24
[Implementation](https://github.com/spacedriveapp/spacedrive/tree/main/crates/p2p/crates/tunnel)
TODO
<Notice type="warning" text="The cryptography has not been implemented for this abstraction. It does not provide any security at this time but it should still be used so when it is implemented we can benefit from it." />
You can wrap an `UnicastStream` with a `sd_p2p_tunnel::Tunnel` to authenticate that the remote peer is who they say they are and to encrypt the data being sent between the two peers.
By default all communication is encrypted between the nodes, however we don't check that the remote peer is who they say they are, or are paired.
So an attacker could setup a modified version of Spacedrive which presents it's own certificate but proxies all traffic between two nodes. This would allow them to view or modify the library data sent over the network. With mDNS being very easy to spoof getting a MITM attack like this is not a far feteched idea.
Using `Tunnel` will prevent this attack by cryptographically verifying the remote peer holds the private key for the library instance they are advertising. This process also acts as an authentication mechanism for the remote peer to ensure they are allowed to request data within the library.
You **should** use this is your communicating with a library on a remote node (Eg. sync, request file) but if you're talking with the node (Eg. Spacedrop) you don't need it.
## Example
```rust
# TODO
```
TODO - https://linear.app/spacedriveapp/issue/ENG-753/spacetunnel-encryption
Refer to [the tests](#todo) to see an example of how to use the protocol.

View File

@@ -5,7 +5,7 @@ index: 21
# Usage
This is a high-level guide of how to build features within Spacedrive on top of the peer-to-peer system. I would recommend referring to this [example PR](#todo) alongside this guide as a practical reference.
This is a high-level guide of how to build features within Spacedrive on top of the peer-to-peer system. I would recommend referring to this [example PR](https://github.com/spacedriveapp/spacedrive/pull/2523) alongside this guide as a practical reference.
Start by adding a new variant to [`Header` enum](https://github.com/spacedriveapp/spacedrive/blob/main/core/src/p2p/protocol.rs) and adjusting the `Header::from_stream` and `Header::to_bytes` implementation to support it.
@@ -75,3 +75,9 @@ let metadata = PeerMetadata::from_hashmap(&peer.metadata()).unwrap();
// You could use the `semver` crate to compare versions
let is_running_version_0_1_0 = metadata.version.as_deref() == Some("0.1.0");
```
## Security
If your devices are sending library scoped data you should ensure you use `sd_p2p_tunnel::Tunnel` to authenticate the library on the remote node.
Refer to [it's docs](/docs/developers/p2p/sd_p2p_tunnel) for more information.