Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

autorelay #5785

Merged
merged 8 commits into from
Dec 18, 2018
Merged

autorelay #5785

merged 8 commits into from
Dec 18, 2018

Conversation

vyzo
Copy link
Contributor

@vyzo vyzo commented Nov 19, 2018

Updates the node construction to automatically construct a routed host and enable autorelay.

Note that instances of the autonat service are required to be (passively) discovered in the network for the autorealy functionality to test for NAT presence, before advertising relay addresses.
This needs to run in the boostrappers and a plus if it is available in other public hosts, so an option to enable it is required.

Depends on

TBD:

  • resolve test failures
  • enable autorelay gating with config option
  • instantiate autonat service with config option.
  • use explicit autorelay libp2p option.

@vyzo vyzo requested a review from Kubuxu as a code owner November 19, 2018 14:06
@ghost ghost assigned vyzo Nov 19, 2018
@ghost ghost added the status/in-progress In progress label Nov 19, 2018
@vyzo vyzo requested a review from Stebalien November 19, 2018 14:06
@vyzo vyzo force-pushed the feat/autorelay branch 2 times, most recently from 9d4cfee to 3700c51 Compare November 19, 2018 14:49
@whyrusleeping
Copy link
Member

Where is autorelay actually being enabled? I don't see any new options

@vyzo
Copy link
Contributor Author

vyzo commented Nov 20, 2018

it's enabled by libp2p when relay is enabled and you pass the new Routing option, which also constructs a routed host.
Should I add an option so that users have to explicitly enable it (or can disable it)?

@vyzo
Copy link
Contributor Author

vyzo commented Nov 20, 2018

Presumably we do want an option in ipfs to enable or disable it, instead of unconditionally enabling.
What should the default state be though?
Perhaps we should start with it disabled as this is a new and experimental feature, and will also require a release cycle to be effective (because new addresses are propagated with identify push, which older nodes do not support).

@vyzo
Copy link
Contributor Author

vyzo commented Nov 20, 2018

options in ipfs/go-ipfs-config#21

// setup routing service
r, err := routingOption(ctx, host, n.Repo.Datastore(), n.RecordValidator)
if err != nil {
return err

This comment was marked as resolved.

@Stebalien
Copy link
Member

Stebalien commented Nov 21, 2018

Whatever happened to fixing libp2p immediately after merging the autorelay change? I thought the entire point of that was to get some code to refactor.

edit: bah humbug. There's no point in introducing an arbitrary dependency to block a really, frickin, awesome feature just because I'm grumpy about something the user will never see.

@vyzo
Copy link
Contributor Author

vyzo commented Nov 21, 2018

The libp2p refactoring is still on, but I don't think it will change the user interface -- so we might as well get the feature out first!

Stebalien added a commit that referenced this pull request Nov 27, 2018
* AutoRelay options for #5785.
* Badger truncate-by-default option for #5275, #5625.

License: MIT
Signed-off-by: Steven Allen <steven@stebalien.com>
@vyzo
Copy link
Contributor Author

vyzo commented Nov 28, 2018

added autorelay gating with config option.

@vyzo
Copy link
Contributor Author

vyzo commented Nov 28, 2018

instantiated the autonat service as well.

@vyzo
Copy link
Contributor Author

vyzo commented Nov 28, 2018

@Stebalien this is complete feature-wise, take another look?

@vyzo vyzo force-pushed the feat/autorelay branch 2 times, most recently from d7a7386 to ab07fe3 Compare November 30, 2018 08:56
@vyzo
Copy link
Contributor Author

vyzo commented Nov 30, 2018

rebased on master.

@Stebalien Stebalien requested a review from djdv December 1, 2018 00:30
@Stebalien
Copy link
Member

  • What is the difference between a RelayHost and an AutoRelayHost?
  • Why does passing the routing option to libp2p enable auto relay? They seem totally unrelated (well, the former seems like a dependency of the latter).

This patch should be able to avoid the routing option dance by always using the libp2p option. We'd need to modify the mock host constructor (a cleaner solution would be to add a Host (constructor) option to libp2p itself but that may be overkill given that we're planning on changing this all up).

@vyzo
Copy link
Contributor Author

vyzo commented Dec 1, 2018

What is the difference between a RelayHost and an AutoRelayHost?

RelayHost is an actual relay, while AutoRelayHost is a host that connects to relays and advertises relay addrs (when NATed).

Why does passing the routing option to libp2p enable auto relay? They seem totally unrelated (well, the former seems like a dependency of the latter).

Well, the routing is necessary for auto relay, but there is no other explicit option. Perhaps we should add one.

We'd need to modify the mock host constructor

I guess we can do that. We'll need the option for explicit autorelay though, otherwise it will be unconditionally enabled.

@vyzo
Copy link
Contributor Author

vyzo commented Dec 4, 2018

Added explicit option in libp2p/go-libp2p#500; we'll have to bubble up, and also merge libp2p/go-libp2p#495

@Stebalien
Copy link
Member

Actually, we can totally test this (I think). We can't simulate NATs but we can, carefully, configure our transports:

  • Peer A: Listens on QUIC only (but can still dial with TCP).
  • Peer B: Has QUIC disabled, has AutoNATService enabled.
  • Peer C: Has QUIC enabled, has RelayHop enabled.
  • Peer D: Has QUIC disabled.
  1. Start all peers.
  2. Connect peer A to peer B and peer C.
  3. Try to connect peer D to peer A, keep retrying every 3 seconds until it works (may take a while).
  4. Check ipfs id on peer A to see if it's announcing a relay address.

Think that will work?

@vyzo
Copy link
Contributor Author

vyzo commented Dec 13, 2018

there are still some obsene delays involved; there is about a 90s delay until the autonat detection boots and fires, which we don't have a way to configure in sharness.
we could add some parameters just for testing though, but it's ugly.

@Stebalien
Copy link
Member

Honestly, I'm fine just having a really slow test for now. We can mark it as EXPENSIVE. We just really should have something.

(we really need to get rid of those delays but we'll probably need an event system to do that)

@vyzo
Copy link
Contributor Author

vyzo commented Dec 13, 2018

ok, let me cook up a ridiculously slow sharness test then -- how do i mark as expensive?

@Stebalien
Copy link
Member

test_expect_success EXPENSIVE "some description" ' ... test ... '

(take a look at the add-and-cat tests).

@vyzo
Copy link
Contributor Author

vyzo commented Dec 17, 2018

So I've cooked up a test as you suggested, but unfortunately it can't work: autorelay only advertises public addresses and there are no public addresses in my NATed laptop :(

@magik6k
Copy link
Member

magik6k commented Dec 17, 2018

This is probably definetly a really bad idea, but - are there any solutions that would allow us to setup fake userspace network and hook ipfs it into using something like LD_PRELOAD?

@Stebalien
Copy link
Member

are there any solutions that would allow us to setup fake userspace network and hook ipfs it into using something like LD_PRELOAD?

Maybe but probably not given that go tends to make raw syscalls. We could also use a syscall filter.

However... we could test this from go with a plugin. That is, we could drop in a special plugin that modifies go-multiaddr-net's Unroutable/Private network variables on load. Thoughts? Is that even possible?

@Stebalien Stebalien added status/blocked Unable to be worked further until needs are met and removed status/in-progress In progress labels Dec 17, 2018
@Stebalien
Copy link
Member

Status: Blocked on at least demonstrating that this works (even if we can't write a test that runs on CI).

@vyzo
Copy link
Contributor Author

vyzo commented Dec 18, 2018

I have confirmed that autorelay works with manual testing.
I started an AutoNAT/RelayHop node in a vps, and tested using a double-NATed laptop node.
I connected the laptop node to the vps node, and after a couple of minutes it started advertising relay addrs.

Transcript:

$ ipfs id

{
        "ID": "QmRozfTYbjdktgjkC9XNjQNKHz4kui5sfNRzkaGqHmRouE",
        "PublicKey": "CAASpgIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDSG2Zlqp
oEyWa498W3NzaiOz642nwkP9jgnggpHWrJ3lL6cv2OzM+n9EREshG4TIHuxjY8unvBby8weDzWPYXO9o
YSR052VKSNzZgsMZ1cjuL6YrNgf9t2l9JeHvHZlEdodYKFwwcWgrAVRjAsVMOpo3zylrz19lYk7b5I2O
QgaX4dSNpjxUuZH1M97IokegHnIKxCqdFdQ03WotlQ08ppzQ/kG0UYiZvLKTxbrFw8wR915oBH9ZQf0t
RVaB+5kbJiVG/UmHyAyCmqpxrhW73UrldU9kIVmFxHFoeqP50stiWVtu/ROmiy040EL/krjv88ftQVvMLtBTUUsnyt2wX5AgMBAAE=",
        "Addresses": [
                "/ip4/127.0.0.1/tcp/4001/ipfs/QmRozfTYbjdktgjkC9XNjQNKHz4kui5sfNRzkaGqHmRouE",
                "/ip4/10.0.1.30/tcp/4001/ipfs/QmRozfTYbjdktgjkC9XNjQNKHz4kui5sfNRzkaGqHmRouE",
                "/ip6/::1/tcp/4001/ipfs/QmRozfTYbjdktgjkC9XNjQNKHz4kui5sfNRzkaGqHmRouE",
                "/ip4/79.167.218.87/tcp/2647/ipfs/QmRozfTYbjdktgjkC9XNjQNKHz4kui5sfNRzkaGqHmRouE"
        ],
        "AgentVersion": "go-ipfs/0.4.19-dev/dad0fa54a",
        "ProtocolVersion": "ipfs/0.1.0"
}

# connect to the relay/autonat node:
$ ipfs swarm connect /ip4/172.104.9.124/tcp/4001/ipfs/QmchgNzyUFyf2wpfDMmpGxMKHA3PkC1f3H2wUgbs21vXoh

# after a couple of minutes relay addrs are advertised as expected:
$ ipfs id

{
        "ID": "QmRozfTYbjdktgjkC9XNjQNKHz4kui5sfNRzkaGqHmRouE",
        "PublicKey": "CAASpgIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDSG2ZlqpoEyWa498W3NzaiOz642nwkP9jgnggpHWrJ3lL6cv2OzM+n9EREshG4TIHuxjY8unvBby8weDzWPYXO9oYSR052VKSNzZgsMZ1cjuL6YrNgf9t2l9JeHvHZlEdodYKFwwcWgrAVRjAsVMOpo3zylrz19lYk7b5I2OQgaX4dSNpjxUuZH1M97IokegHnIKxCqdFdQ03WotlQ08ppzQ/kG0UYiZvLKTxbrFw8wR915oBH9ZQf0tRVaB+5kbJiVG/UmHyAyCmqpxrhW73UrldU9kIVmFxHFoeqP50stiWVtu/ROmiy040EL/krjv88ftQVvMLtBTUUsnyt2wX5AgMBAAE=",
        "Addresses": [
                "/ip4/127.0.0.1/tcp/4001/ipfs/QmRozfTYbjdktgjkC9XNjQNKHz4kui5sfNRzkaGqHmRouE",
                "/ip4/10.0.1.30/tcp/4001/ipfs/QmRozfTYbjdktgjkC9XNjQNKHz4kui5sfNRzkaGqHmRouE",
                "/ip6/::1/tcp/4001/ipfs/QmRozfTYbjdktgjkC9XNjQNKHz4kui5sfNRzkaGqHmRouE",
                "/ip4/79.167.218.87/ipfs/QmRozfTYbjdktgjkC9XNjQNKHz4kui5sfNRzkaGqHmRouE",
                "/ip6/2600:3c03::f03c:91ff:fe87:a3b4/tcp/4001/ipfs/QmchgNzyUFyf2wpfDMmpGxMKHA3PkC1f3H2wUgbs21vXoh/p2p-circuit/ipfs/QmRozfTYbjdktgjkC9XNjQNKHz4kui5sfNRzkaGqHmRouE",
                "/ip4/172.104.9.124/tcp/4001/ipfs/QmchgNzyUFyf2wpfDMmpGxMKHA3PkC1f3H2wUgbs21vXoh/p2p-circuit/ipfs/QmRozfTYbjdktgjkC9XNjQNKHz4kui5sfNRzkaGqHmRouE"
        ],
        "AgentVersion": "go-ipfs/0.4.19-dev/dad0fa54a",
        "ProtocolVersion": "ipfs/0.1.0"
}

@vyzo
Copy link
Contributor Author

vyzo commented Dec 18, 2018

Steps to reproduce:

  1. Create a public node with AutoNAT/RelayHop Enabled:
ipfs config --json Swarm.EnableRelayHop true
ipfs config --json Swarm.EnableAutoNATService true
ipfs config --json Swarm.EnableAutoRelay true
  1. Start a node behind a bad NAT with autorelay enabled (ipfs config --json Swarm.EnableAutoRelay true), and connect to your relay using ipfs warm connect ...

  2. Wait a couple of minutes, and check the output of ipfs id; it should change the public addresses to the naked ip plus the public relay addresses.

@Stebalien Stebalien removed the status/blocked Unable to be worked further until needs are met label Dec 18, 2018
@ghost ghost added the status/in-progress In progress label Dec 18, 2018
@vyzo
Copy link
Contributor Author

vyzo commented Dec 18, 2018

we also need to update go-libp2p-autonat-svc to 1.0.4 for go-libp2p 6.0.29 (once this has bubbled up).

vyzo added 8 commits December 18, 2018 11:30
…utorelay

License: MIT
Signed-off-by: vyzo <vyzo@hackzen.org>
License: MIT
Signed-off-by: vyzo <vyzo@hackzen.org>
License: MIT
Signed-off-by: vyzo <vyzo@hackzen.org>
License: MIT
Signed-off-by: vyzo <vyzo@hackzen.org>
License: MIT
Signed-off-by: vyzo <vyzo@hackzen.org>
License: MIT
Signed-off-by: vyzo <vyzo@hackzen.org>
PeerHost is now initialized before calling it.

License: MIT
Signed-off-by: vyzo <vyzo@hackzen.org>
License: MIT
Signed-off-by: vyzo <vyzo@hackzen.org>
@Stebalien Stebalien merged commit 526d619 into master Dec 18, 2018
@ghost ghost removed the status/in-progress In progress label Dec 18, 2018
@Stebalien Stebalien deleted the feat/autorelay branch December 18, 2018 20:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Host/Service interface design
5 participants