dennis-tra / pcp

πŸ“¦ Command line peer-to-peer data transfer tool based on libp2p.
Apache License 2.0
1.07k stars 57 forks source link
cli data-transfer dht file-sharing hacktoberfest ipfs libp2p mdns pake peer-to-peer

pcp - Peer Copy

standard-readme compliant Go Report Card Maintainability Latest test suite run result [Github Releases Download Count]()

Command line peer-to-peer data transfer tool based on libp2p.

Demo animation

This tool was published at the IFIP 2021 conference. You can find the preprint below.

Table of Contents

Motivation

There already exists a long list of file transfer tools (see Related Efforts), so why bother building another one? The problem I had with the existing tools is that they rely on a limited set of servers to orchestrate peer matching and data relaying which poses a centralisation concern. Many of the usual centralisation vs. decentralisation arguments apply here, e.g. the servers are single points of failures, the service operator has the power over whom to serve and whom not, etc. Further, as this recent issue in croc shows, this is a real risk for sustainable operation of the provided service.

Project Status

The tool is in a very early stage, and I'm aware of performance, usability and security issues. Don't use it for anything serious. Although I criticised tools like magic-wormhole or croc above, they are amazing and way more mature.

There are also drawbacks with this approach: It's slower than established centralised methods if you want to transmit data across network boundaries. A DHT query to find your peer can easily take several minutes. Further, the bandwidth and geographic location of a potential relaying peer is not guaranteed which can lead to long transmission times.

How does it work?

When running pcp send you'll see four random words from a list of the Bitcoin improvement proposal BIP39. There are lists in nine different languages of 2048 words each, currently only english is supported. The first word is interpreted as a channel ID in the range from 0 to 2047. pcp advertises the identifier /pcp/{unix-timestamp}/{channel-id} in its local network via mDNS and a hashed version of this string in the DHT of IPFS. The unix timestamp is the current time truncated to 5 minutes and the prefix /pcp is the protocol prefix. In the future: When you enter a new 5-minute interval while pcp send is running it advertises an updated identifier.

To receive the file your peer enters pcp receive four-words-from-above and pcp uses the first word together with the current time truncated to 5 minutes to find the sending peer in the DHT and in your local network via mDNS. It also searches for an identifier of the previous 5-minute interval. As soon as the peer is found, both do a password authenticated key exchange (PAKE) to authenticate each other. In this procedure a comparably weak password (four-words-from-above) gets replaced with a strong session key that is used to encrypt all future communication. The default TLS encryption that libp2p provides is not sufficient in this case as we could still, in theory, talk to a wrong peer - just encrypted.

After the peer is authenticated the receiver must confirm the file transfer, and the file gets transmitted.

Usage

The sending peer runs:

$ pcp send my_file
Code is:  bubble-enemy-result-increase
On the other machine run:
    pcp receive bubble-enemy-result-increase

The receiving peer runs:

$ pcp receive bubble-enemy-result-increase
Looking for peer bubble-enemy-result-increase...

If you're on different networks the lookup can take quite long (~ 2-3 minutes). Currently, there is no output while both parties are working on peer discovery, so just be very patient.

Install

Package managers

brew install pcp

It's on the roadmap to also distribute pcp via apt, yum, scoop and more ...

Release download

Head over to the releases and download the latest archive for your platform.

From source

To compile it yourself run:

go install github.com/dennis-tra/pcp/cmd/pcp@latest # Go 1.13 or higher is required

Make sure the $GOPATH/bin is in your PATH variable to access the installed pcp executable.

Development

Protobuf definitions

First install the protoc compiler:

make tools # downloads gofumpt and protoc
make proto # generates protobuf

The current proto definitions were generated with libprotoc 3.14.0.

Feature Roadmap

Shamelessly copied from croc:

You can find a project plan in the project tab of this page. Some other ideas I would love to work on include:

Related Efforts

Maintainers

@dennis-tra.

Acknowledgments

Contributing

Feel free to dive in! Open an issue or submit PRs.

Research

This tool was submitted to the International Federation for Information Processing 2021 (IFIP '21) conference and accepted for publication. You can find the preprint here.

Cite the paper with this BibTeX entry: Jesse Pinkman
@inproceedings{Trautwein2021,
  title        = {Introducing Peer Copy - A Fully Decentralized Peer-to-Peer File Transfer Tool},
  author       = {Trautwein, Dennis and Schubotz, Moritz and Gipp, Bela},
  year         = 2021,
  month        = {June},
  booktitle    = {2021 IFIP Networking Conference (IFIP Networking)},
  publisher    = {IEEE},
  address      = {Espoo and Helsinki, Finland},
  doi          = {10.23919/IFIPNetworking52078.2021.9472842},
  note         = {ISBN 978-3-9031-7639-3},
  topic        = {misc}
}

Support

It would really make my day if you supported this project through Buy Me A Coffee.

Other Projects

You may be interested in one of my other projects:

License

Apache License Version 2.0 Β© Dennis Trautwein