NAT Traversal techniques for p2p communication

Related tags

Cryptography p2p
Overview

P2P NAT-Traversal

Crate Documentation Linux/OSX/Windows
Documentation Build Status

The goal of this crate is to provide a robust and crypto-secure NAT traversal for peer to peer connection. It assumes publicly reachable rendezvous servers are provided. The server code itself is in the crate too, so the crate can either be used to deploy a server or used for peer to peer client communication or both simultaneously - for e.g. if you run the server on a port forwarded endpoint, it will be publicly available for others to rendezvous while you could choose normal NAT traversal mechanisms to communicate with other peers.

Please refer to the documentation above for detailed explanation. The examples and the integration tests show how the crate can be used.

Comments
  • bincode version not valid

    bincode version not valid

    When building with p2p as a dependency I get this error:

    error: no matching version `~1.0.0-alpha6` found for package `bincode` (required by `p2p`)
    location searched: registry https://github.com/rust-lang/crates.io-index
    versions found: 0.8.0, 0.7.0, 0.6.1, ...
    
    opened by shnupta 3
  • Licensing

    Licensing

    I'm interested in using this library in my Apache licensed code, however I understand that this license is only one way compatibility with your GPL. Could you help me understand if there is any way in which I can use your code in my Apache licensed code?

    opened by mboogerd 2
  • TCP STUN requests fails with only one STUN server

    TCP STUN requests fails with only one STUN server

    cargo run --example tcp_rendezvous_connect -- --disable-igd --traversal-server=86.100.203.141:3000 --relay=86.100.203.141:4000 "I'm 4000" this command runs TCP example which initially does some STUN requests to determine it's public address. Unfortunately it fails with such logs:

    TRACE:p2p::rendezvous_addr: got a new server to try: 86.100.203.141:3000
    TRACE:p2p::rendezvous_addr: in PublicAddrsFromStun::poll() loop
    TRACE:p2p::rendezvous_addr: query returned error: error connecting to echo server: Cannot assign requested address (os error 99)
    TRACE:p2p::tcp::stream: got rendezvous address: None
    

    I did some research and it seems like you cannot bind and connect multiple times with the same source/destination address pair: https://idea.popcount.org/2014-04-03-bind-before-connect/

    I've also got small python script to reproduce this:

    import socket
    
    
    def reusable_socket(addr):
        sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
        sock.bind(addr)
        return sock
    
    
    def main():
        sock = reusable_socket(('0.0.0.0', 0))
        our_addr = sock.getsockname()
        print('our bind addr:', our_addr)
    
        sock2 = reusable_socket(our_addr)
        sock2.connect(('86.100.203.141', 3000))
        sock2.send(b'ECHOADDR')
        resp = sock2.recv(4096)
        print('Resp:', resp)
    
        # this works V
        # sock3 = reusable_socket(('0.0.0.0', 0))
        # this will fail V
        sock3 = reusable_socket(our_addr)
        sock3.connect(('86.100.203.141', 3000))
        sock3.send(b'ECHOADDR')
        resp = sock3.recv(4096)
        print('Resp:', resp)
    
    
    main()
    

    it fails with such output:

    our bind addr: ('0.0.0.0', 45121)
    Resp: b'\x13\x00\x00\x00\x00\x00\x00\x0078.60.234.207:45121'
    Traceback (most recent call last):
      File "main.py", line 33, in <module>
        main()
      File "main.py", line 27, in main
        sock3.connect(('86.100.203.141', 3000))
    OSError: [Errno 99] Cannot assign requested address
    

    So the first connect and request succeeds, but the next one fails and the error message basically says that another socket already has a connection with the same source IP:port to the same destination IP:port .

    opened by povilasb 2
  • Increase rendezvous connection info exchange timeouts

    Increase rendezvous connection info exchange timeouts

    With too short timeouts connections might be prematurily dropped - especially with manual tests.

    Also, note that this change indicates duplicate code. It would be really easy to extract it. I simply wonder how to deal with different error types:

                            channel
                            .map_err(TcpRendezvousConnectError::ChannelRead)
                            .next_or_else(|| TcpRendezvousConnectError::ChannelClosed)
                            .with_timeout(
                                Duration::from_secs(RENDEZVOUS_INFO_EXCHANGE_TIMEOUT_SEC),
                                &handle1
                            )
                            .and_then(|opt| opt.ok_or(TcpRendezvousConnectError::ChannelTimedOut))
    

    In case of UDP code is identical except that errors are of UdpRendezvousConnectError type.

    opened by povilasb 2
  • Rendezvous IGD port timeout should be configurable/disableable

    Rendezvous IGD port timeout should be configurable/disableable

    Rather than always set to 5min. It's possible (?) that some routers might kill a connection if the port expires while there's an active connection on it. We should investigate whether this fear is justified and whether we need to make it so the timeout can be disabled.

    opened by canndrew 2
  • Fix builds

    Fix builds

    Some examples would not build without "socket-collection/enable-udt" feature. Also specified socket-collection version to have reproducible builds.

    opened by povilasb 1
  • test/netsim: expand netsim test with different NAT types

    test/netsim: expand netsim test with different NAT types

    Also run rustfmt

    Sorry the rustfmt changes are mixed in with the actual changes. I should have commited the actual changes first. The only actual change is to the netsim test for UDP sockets.

    opened by canndrew 1
  • More tests

    More tests

    Adds UdpRendezvousServer integration test. This is a smaller scope than nat_traversal test and will be a good example for such future tests. Also, it will keep us safer while doing safe_crypto integration.

    opened by povilasb 0
  • Archivation

    Archivation

    I propose to archive this repository.

    I have been trying to rework this crate all day such that it works with modern rust compilers. I failed since multiple integral dependencies of this crate (namely maidsafe_utilities, socket-collection) are archived themselves (and do not compile anymore with recent versions of rust). I think further development to this library is not productive as further development will need to address dependencies of these archived and thus unmaintained repositories.

    However, reusing parts of this crate to create a newer, more modern library accomplishing a similar task seems useful I can't find many alternatives in the rust ecosystem to this for peer to peer connections.

    This is my opinion, if the developers think differently, feel free to dismiss this issue.

    opened by jonay2000 1
  • compilation fails to build with rust-1.48

    compilation fails to build with rust-1.48

    Hello, thanks for creating this project.

    I am kinda new in Rust, but I am getting the error compiling the lib

    error[E0713]: borrow may still be in use when destructor runs
       --> /home/william/.cargo/registry/src/github.com-1ecc6299db9ec823/url-1.5.1/src/form_urlencoded.rs:251:40
        |
    249 | impl<'a> Target for ::UrlQuery<'a> {
        |      -- lifetime `'a` defined here
    250 |     fn as_mut_string(&mut self) -> &mut String { &mut self.url.serialization }
    251 |     fn finish(self) -> &'a mut ::Url { self.url }
        |                                        ^^^^^^^^ - here, drop of `self` needs exclusive access to `*self.url`, because the type `UrlQuery<'_>` implements the `Drop` trait
        |                                        |
        |                                        returning this value requires that `*self.url` is borrowed for `'a`
    
    error: aborting due to previous error
    
    For more information about this error, try `rustc --explain E0713`.
    error: could not compile `url`
    
    To learn more, run the command again with --verbose.
    

    Ubuntu 20.04 cargo 1.48.0 (65cbdd2dc 2020-10-14) rustc 1.48.0 (7eac88abb 2020-11-16)

    Reading a bit I think is caused by rust-lang/rust#64221 (NLL warnings in the 2015 edition are now hard errors)

    opened by WilliamTakeshi 2
  • lint `private_no_mangle_fns`/`private_no_mangle_statics` has been removed

    lint `private_no_mangle_fns`/`private_no_mangle_statics` has been removed

    When compiling in nightly rustc 1.33.0-nightly (fb86d604b 2018-12-27) or stable rustc 1.31.1 (b6c32da9b 2018-12-18), the following errors appears :

    error: lint `private_no_mangle_fns` has been removed: `no longer a warning, #[no_mangle] functions always exported`
       --> src/lib.rs:229:5
        |
    229 |     private_no_mangle_fns,
        |     ^^^^^^^^^^^^^^^^^^^^^
        |
    note: lint level defined here
       --> src/lib.rs:219:5
        |
    219 |     warnings
        |     ^^^^^^^^
        = note: #[forbid(renamed_and_removed_lints)] implied by #[forbid(warnings)]
    
    error: lint `private_no_mangle_statics` has been removed: `no longer a warning, #[no_mangle] statics always exported`
       --> src/lib.rs:230:5
        |
    230 |     private_no_mangle_statics,
        |     ^^^^^^^^^^^^^^^^^^^^^^^^^
    
    error: aborting due to 2 previous errors
    
    error: Could not compile `p2p`.
    

    Removing both deny lints allow to build.

    opened by nanocryk 0
  • Type has been exposed only for testing purposes

    Type has been exposed only for testing purposes

    Type here has been exposed only for testing purpose. See if there's a better way to test to not have to expose it or expose it only for non-production as exposure conveys wrong information to a reader.

    opened by ustulation 0
  • Incompatible license

    Incompatible license

    p2p is a nice library.

    But maybe we can not use p2p as MIT/BSD-3 license?

    $ cargo lichking check
    warning: IANAL: This is not legal advice and is not guaranteed to be correct.
    error: p2p cannot include package sha1, license BSD-3-Clause is incompatible with Any(MIT, BSD-3-Clause)
    error: p2p cannot include package future-utils, license GPL-2.0-only is incompatible with Any(MIT, BSD-3-Clause)
    error: p2p cannot include package tokio-shared-udp-socket, license GPL-3.0-only is incompatible with Any(MIT, BSD-3-Clause)
    error: p2p cannot include package config_file_handler, license GPL-3.0-only is incompatible with Any(MIT, BSD-3-Clause)
    error: p2p cannot include package fuchsia-zircon-sys, license BSD-3-Clause is incompatible with Any(MIT, BSD-3-Clause)
    error: p2p cannot include package unwrap, license GPL-3.0-only is incompatible with Any(MIT, BSD-3-Clause)
    error: p2p cannot include package netsim, license GPL-2.0-only is incompatible with Any(MIT, BSD-3-Clause)
    error: p2p cannot include package fuchsia-zircon, license BSD-3-Clause is incompatible with Any(MIT, BSD-3-Clause)
    error: p2p cannot include package net-literals-impl, license GPL-3.0-only is incompatible with Any(MIT, BSD-3-Clause)
    error: p2p cannot include package future-utils, license GPL-2.0-only is incompatible with Any(MIT, BSD-3-Clause)
    error: p2p cannot include package net-literals, license GPL-3.0-only is incompatible with Any(MIT, BSD-3-Clause)
    error: p2p cannot include package future-utils, license GPL-2.0-only is incompatible with Any(MIT, BSD-3-Clause)
    error: p2p cannot include package get_if_addrs, license GPL-3.0-only is incompatible with Any(MIT, BSD-3-Clause)
    error: p2p cannot include package capabilities, license MPL-2.0 is incompatible with Any(MIT, BSD-3-Clause)
    error: p2p cannot include package maidsafe_utilities, license GPL-3.0-only is incompatible with Any(MIT, BSD-3-Clause)
    error: Incompatible license
    
    opened by TheWaWaR 5
Owner
Spandan Sharma
A Byzantine General without problems
Spandan Sharma
An implementation of Jakobsson's Fractal Hash Sequence Traversal algorithm

fractal-hash-traversal An implementation of Jakobsson's Fractal Hash Sequence Traversal algorithm. There is at least one hash traversal algorithm that

Dan Cline 1 Jan 12, 2022
Rust implementation of the Inter-Blockchain Communication (IBC) protocol.

ibc-rs Rust implementation of the Inter-Blockchain Communication (IBC) protocol. This project hosts the ibc rust crate which defines the main data str

COSMOS 37 Dec 26, 2022
Kryptokrona SDK in Rust for building decentralized private communication and payment systems.

Kryptokrona Rust SDK Kryptokrona is a decentralized blockchain from the Nordic based on CryptoNote, which forms the basis for Monero, among others. Cr

null 5 May 25, 2023
A fully p2p cli chat utility written in rust.

P2P Chat Client This is a simple demonstration of a peer to peer chat client, written entirely in rust utilising the libp2p library. Demo On two seper

Josiah Bull 7 Dec 17, 2022
A multiplexed p2p network framework that supports custom protocols

Tentacle Overview This is a minimal implementation for a multiplexed p2p network based on yamux that supports mounting custom protocols. Architecture

漂流 188 Dec 19, 2022
P2P Network to verify authorship & ownership, store & deliver proofs.

Anagolay Network Node Anagolay is a next-generation framework for ownerships, copyrights and digital licenses. ?? Local Development The installation a

Anagolay Network 5 May 30, 2022
Custom p2p swaps powered by Solana blockchain

Peer to peer, decentralized protocol which allow direct swaps between 2 network participants for custom tokens without liquidity pools on Solana blockchain.

Ilia 3 Mar 18, 2022
Biddi Network enables custom p2p swaps in Solana ocean 🌊.

Peer to peer, decentralized protocol which allow direct swaps between 2 network participants for custom tokens without liquidity pools on Solana blockchain.

Biddi Network 2 Nov 1, 2022
Low-level Bitcoin P2P Network Client

Peerlink What is Peerlink? Peerlink is a low-level network client for the Bitcoin P2P network written in Rust. It uses a nonblocking reactor to accept

Alfred Hodler 6 Dec 23, 2022
Open source p2p share for devs to share anything with teammates across machines securely.

Secure share Share anything with teammates across machines via CLI. Share is a tool for secure peer-to-peer connections, enabling direct communication

Onboardbase 10 Aug 4, 2023
Ethereum (and Ethereum like) indexer using P2P message to fetch blocks and transactions

Ethereum P2P indexer This project is an indexer for Ethereum and Ethereum forks. It takes advantage of the ETH (Ethereum Wire Protocol) to fetch block

null 5 Nov 10, 2023
Reliable p2p network connections in Rust with NAT traversal

Reliable p2p network connections in Rust with NAT traversal. One of the most needed libraries for any server-less / decentralised projects

MaidSafe-Archive 948 Dec 20, 2022
Reliable p2p network connections in Rust with NAT traversal

Reliable p2p network connections in Rust with NAT traversal. One of the most needed libraries for any server-less, decentralised project.

MaidSafe-Archive 948 Dec 20, 2022
A fast and stable reverse proxy for NAT traversal, written in Rust

rathole A fast and stable reverse proxy for NAT traversal, written in Rust rathole, like frp, can help to expose the service on the device behind the

Yujia Qiao 4.6k Dec 30, 2022
Easy c̵̰͠r̵̛̠ö̴̪s̶̩̒s̵̭̀-t̶̲͝h̶̯̚r̵̺͐e̷̖̽ḁ̴̍d̶̖̔ ȓ̵͙ė̶͎ḟ̴͙e̸̖͛r̶̖͗ë̶̱́ṉ̵̒ĉ̷̥e̷͚̍ s̷̹͌h̷̲̉a̵̭͋r̷̫̊ḭ̵̊n̷̬͂g̵̦̃ f̶̻̊ơ̵̜ṟ̸̈́ R̵̞̋ù̵̺s̷̖̅ţ̸͗!̸̼͋

Rust S̵̓i̸̓n̵̉ I̴n̴f̶e̸r̵n̷a̴l mutability! Howdy, friendly Rust developer! Ever had a value get m̵̯̅ð̶͊v̴̮̾ê̴̼͘d away right under your nose just when

null 294 Dec 23, 2022
Lightweight p2p library. Support build robust stable connection on p2p/distributed network.

Chamomile Build a robust stable connection on p2p network features Support build a robust stable connection between two peers on the p2p network. Supp

CympleTech 94 Jan 6, 2023
OptFrame is an optimization framework focused in metaheuristic techniques

optframe-rust Welcome to OptFrame project in Rust. What is OptFrame? OptFrame is an optimization framework focused in metaheuristic techniques, develo

OptFrame 4 Jan 30, 2022
RustRedOps is a repository dedicated to gathering and sharing advanced techniques and malware for Red Team, with a specific focus on the Rust programming language. (In Construction)

RustRedOps In Construction.... The project is still under development Overview RustRedOps is a repository that houses various tools and projects relat

João Victor 17 Dec 14, 2023
A modern, simple TCP tunnel in Rust that exposes local ports to a remote server, bypassing standard NAT connection firewalls

bore A modern, simple TCP tunnel in Rust that exposes local ports to a remote server, bypassing standard NAT connection firewalls. That's all it does:

Eric Zhang 6.2k Dec 31, 2022
Narrowlink securely connects devices and services together, even when both nodes are behind separate NAT

Narrowlink Narrowlink is a self-hosted platform that allows you to establish secure remote connections between devices within a network that may be hi

Narrowlink 355 Aug 17, 2023