holepunchto / hyperdht

The DHT powering Hyperswarm
https://docs.holepunch.to
MIT License
323 stars 46 forks source link

Same code works except in DigitalOcean servers #60

Closed LuKks closed 2 years ago

LuKks commented 2 years ago

Running server.js and client.js on the same machine works. Server.js on my machine and client.js on DigitalOcean also works, and vice versa (me as client and DO as server).

Except runinng both in separated DigitalOcean servers: Server: https://gist.github.com/LuKks/7b56e221d9e3214bce56f562d0d65c60 Client: https://gist.github.com/LuKks/82c5816dbcafcee73cf7fcaecec449fc

events.js:377
      throw er; // Unhandled 'error' event
      ^

Error: Connect aborted
    at Pair.c.pair.ondestroy (/root/hyperforward/node_modules/@hyperswarm/dht/lib/connect.js:218:38)
    at Pair.destroy (/root/hyperforward/node_modules/@hyperswarm/dht/lib/socket-pairer.js:485:10)
    at Timeout.destroy (/root/hyperforward/node_modules/@hyperswarm/dht/lib/socket-pairer.js:687:5)
    at listOnTimeout (internal/timers.js:559:11)
    at processTimers (internal/timers.js:500:7)
Emitted 'error' event on NoiseSecretStream instance at:
    at WritableState.afterDestroy (/root/hyperforward/node_modules/streamx/index.js:442:19)
    at NoiseSecretStream._destroy (/root/hyperforward/node_modules/@hyperswarm/secret-stream/index.js:365:5)
    at WritableState.updateNonPrimary (/root/hyperforward/node_modules/streamx/index.js:189:16)
    at WritableState.update (/root/hyperforward/node_modules/streamx/index.js:174:70)
    at ReadableState.afterOpen (/root/hyperforward/node_modules/streamx/index.js:499:27)
    at NoiseSecretStream._predestroy (/root/hyperforward/node_modules/@hyperswarm/secret-stream/index.js:308:7)
    at NoiseSecretStream.destroy (/root/hyperforward/node_modules/streamx/index.js:570:12)
    at Pair.c.pair.ondestroy (/root/hyperforward/node_modules/@hyperswarm/dht/lib/connect.js:218:23)
    at Pair.destroy (/root/hyperforward/node_modules/@hyperswarm/dht/lib/socket-pairer.js:485:10)
    at Timeout.destroy (/root/hyperforward/node_modules/@hyperswarm/dht/lib/socket-pairer.js:687:5)

Just sharing, the more I try to understand the more I know it's a great lib!

LuKks commented 2 years ago

Aside from tthe issue: The gists represent what I would like to do with DHT or Hyperswarm, just forward http servers or socks proxies over p2p but after the first lookup shouldn't be need for a bootstrap server to connect again (while having a connection to keep alive the holepunch). Makes sense? Like ssh -R, ssh -L and ssh -D but p2p.

The problem is that local can close the peer socket, for example, pump shouldn't close the peer connection otherwise it has to lookup again, solveable manually doing pipe without passing end but I don't like to (multiplex?) reuse the same socket for all connections. I mean, each local connection should have his own peer connection, without extra lookups for lower latency.

Having server and client in the same machine it takes 1.6 seconds to lookup which is impressive for a first time but it's not for each time: image How can the delay be improved?

I'm trying to understand addNodes and what Mafintosh said in the Hyperswarm issue.

mafintosh commented 2 years ago

Can you define what you mean by “seperated digital ocean servers”, then I’ll try to repro

LuKks commented 2 years ago

I just created two servers in DigitalOcean, nothing special.

image

Both:

curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
apt install -y nodejs

mkdir hyper
cd hyper/
npm init -y
npm i @hyperswarm/dht express pump node-fetch@2.6.5

Server:

nano server.js # and paste content
node server.js

Client:

nano client.js # and paste content
node client.js
pfrazee commented 2 years ago

Sanity check: does DO have some firewall rules that need tweaking? (AWS and GCP do)

LuKks commented 2 years ago

Oh, it might be that. As it was working home->DO and also DO->home, I just assumed DO->DO should work the same way.

Before sending this comment, I'm playing with utp-native and DO->DO doesn't seem to work.

mafintosh commented 2 years ago

Ill check thanks. You not blocking all udp/tcp traffic or something like that?

LuKks commented 2 years ago

I think traffic, ports, etc are open by default. image

I opened this issue because I thought it was an error with the library, I mean I don't need the DigitalOcean servers working so maybe it's correct to close it.

The first thing was, I saw this video: image https://youtu.be/TiMeoQt3K4g?t=106

Where it says he used two DO servers, that also helped me to think that DHT would just work.

To be sure, I just deployed a hello world express and the port was open. The unique difference is, in the video it's mentioned that one server is in New York and the second server in other region.

mafintosh commented 2 years ago

It should obvs work with zero config. Let me try to repro and get back to you. Prob something silly

mafintosh commented 2 years ago

@LuKks hmm, can't repro, can you show me ip addr from both servers here?

mafintosh commented 2 years ago

(just made two DO instances and run a simple server and client on each) @LuKks can you potentially join the discord at https://discord.com/channels/709519409932140575/709519410557222964 and DM me otherwise to debug.

mafintosh commented 2 years ago

Also I might be misunderstanding your picture above, but are you running client and server on the same machine or two different ones?

LuKks commented 2 years ago

It's not the real output of both servers, I already deleted them but this should give you an idea of the outputs: ip addr

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether b6:59:0b:72:16:46 brd ff:ff:ff:ff:ff:ff
    inet 157.230.5.155/20 brd 157.230.15.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet 10.10.0.7/16 brd 10.10.255.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::b459:bff:fe72:1646/64 scope link 
       valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 0e:58:53:69:19:3d brd ff:ff:ff:ff:ff:ff
    inet 10.116.0.4/20 brd 10.116.15.255 scope global eth1
       valid_lft forever preferred_lft forever
    inet6 fe80::c58:53ff:fe69:193d/64 scope link 
       valid_lft forever preferred_lft forever

I can create them again and give you access using your public key, and before that I could also prepare the scripts in the servers, is that cool?

About Discord, is the link expired or something? image

My username is: LuKks#9831

Also I might be misunderstanding your picture above, but are you running client and server on the same machine or two different ones?

Different ones, the idea was having two peers in different places, addresses, etc. That's why there is two servers in the example.

LuKks commented 2 years ago

Also I might be misunderstanding your picture above, but are you running client and server on the same machine or two different ones?

Ooh, the screenshot with delay 1402 ms, etc it was something not related with the actual issue, my bad for mixing ideas. This entire comment wasn't related: https://github.com/hyperswarm/dht/issues/60#issuecomment-951812488

mafintosh commented 2 years ago

Does https://chat.hypercore-protocol.org work?

mafintosh commented 2 years ago

Ah the ip addr only help from the actual machine but no worries. I asked if it's the same cause I notice the hostname is the same in your screenshot above.

Can you in detail explain (if you remember) how you set up the two instances so I can try to repro? Ie, where they in the same region etc etc.

mafintosh commented 2 years ago

Unrelated, but don't set the ephemeral flags, those are 99.9% for testing. Just use the defaults. You also don't have to call node.ready(), it's generally much faster to not wait for that, unless you want to print out debug info.

Can you also try if you can reproduce yourself btw?

LuKks commented 2 years ago

Ooh, good one, they had the same hostname but were actually different servers, same region (NY1) tho.

I added your public key so you have SSH access to the next mentioned machines. (now I don't like my keys, you're using ed25519 which seems cool lol)

Machine A: root@198.199.72.217

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether ce:99:65:48:2f:80 brd ff:ff:ff:ff:ff:ff
    inet 198.199.72.217/24 brd 198.199.72.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet 10.10.0.8/16 brd 10.10.255.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::cc99:65ff:fe48:2f80/64 scope link 
       valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether ce:7c:09:7d:67:f1 brd ff:ff:ff:ff:ff:ff
    inet 10.116.0.5/20 brd 10.116.15.255 scope global eth1
       valid_lft forever preferred_lft forever
    inet6 fe80::cc7c:9ff:fe7d:67f1/64 scope link 
       valid_lft forever preferred_lft forever

Machine B: root@68.183.102.101

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 52:64:00:11:89:86 brd ff:ff:ff:ff:ff:ff
    inet 68.183.102.101/20 brd 68.183.111.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet 10.10.0.9/16 brd 10.10.255.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::5064:ff:fe11:8986/64 scope link 
       valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 1a:48:73:87:37:8d brd ff:ff:ff:ff:ff:ff
    inet 10.116.0.6/20 brd 10.116.15.255 scope global eth1
       valid_lft forever preferred_lft forever
    inet6 fe80::1848:73ff:fe87:378d/64 scope link 
       valid_lft forever preferred_lft forever

I ran node ~/hyper/server.js in machine A, later node ~/hyper/client.js in machine B.

The new invite link worked, for a moment I thought it was a p2p chat via hypercore or something.

About the ready() being slow, yes I read multiple times all the docs lol and there is a note somewhere, but as this was something like a test I thought it was okay to use it here. Tell me if you prefer that I reproduce the error without the ready().

mafintosh commented 2 years ago

Amazing, thanks for doing that! I'll try now

mafintosh commented 2 years ago

Okay, Hyperbeam works 100% reliable there as well (that's v good!). Are you sure we weren't rerunning your server script multiple places btw, whilst having your DO box run it? I noticed it's always using the same key pair and the swarm will route the client to the last server who ran it :)

mafintosh commented 2 years ago

Was an actual bug! Fixed above and in the commit after where i fix the fix 🤣