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

How to achieve punching behind nat or firewall, Is there an example? #312

Closed
jiangsuwwj1 opened this issue Apr 15, 2018 · 13 comments
Closed

Comments

@jiangsuwwj1
Copy link

I want to achieve p2p communication through libp2p, and these two are in the private network, how should I do?

@upperwal
Copy link
Contributor

What you need is a mechanism for Peer Discovery and Port mapping for NAT.

You can look at this example for bootstrapping.

NAT Port mapping is taken care by go-libp2p-nat which can be used as follows.

// create a network.
// Docs: https://godoc.org/github.com/libp2p/go-libp2p-swarm#NewNetwork
network, err := swarm.NewNetwork(ctx, sourceMultiAddr, ...)

// now create a host and pass NATManager as hostOpt
natMgr := basichost.NewNATManager(network)
hostOpt := basichost.HostOpts{
        NATManager: natMgr,
}
host := basichost.New(network, hostOpt)

NATManager will take care of port mapping.

@agahEbrahimi
Copy link

agahEbrahimi commented Apr 15, 2018

Does the bootstrap example work correctly outside of the local network?

@upperwal
Copy link
Contributor

@agahEbrahimi If I can understand your question correctly you are talking about port mapping incase of NAT.

If so, first of all I haven't tested it, so not sure. But the example is using NATManager during host creation (here) so it should work.

Just compile and run it.

@agahEbrahimi
Copy link

@upperwal No, I'm referring to the peer discovery and not the port mapping. Sorry I phrased my question incorrectly.

@upperwal
Copy link
Contributor

I believe it should work. Just try it. More info on compiling here

@agahEbrahimi
Copy link

agahEbrahimi commented Apr 15, 2018

Is it just on a local network or does it work across routers (over internet) too?
Because in the readMe it says to run it on a different terminal (same pc), but what about different computer or even a different network?

@upperwal
Copy link
Contributor

Yes, you can run it across networks (the internet) easily if your system has a public IP address and not so easily if they are behind NAT (have a private IP address).

Incase of public IP's you just have to replace 127.*.*.* or 192.168.*.* with your public IP's.

Incase of a NAT (private IP's), process to establish connection will be complicated (don't worry everything is taken care within libp2p). Libp2p will use NAT port mapping (the thing I was talking about earlier) to convert LOCAL_IP:LOCAL_PORT to PUBLIC_IP:PUBLIC_PORT

You need to know what PUBLIC_IP:PUBLIC_PORT mapping is done by NAT Manager. For example using a bootstrap node to store all the incoming nodes info and giving it to the nodes requesting for it (DHT).

@agahEbrahimi
Copy link

agahEbrahimi commented Apr 15, 2018

Ah, so I just change the IPs in the Go code to their respective public IPs and they would be able to find each (after the Nat Port mapping process which you were talking about)? but wouldn't they still have to have the session hash?
> ./routed-echo -l 10000 2018/02/19 12:22:32 I can be reached at: 2018/02/19 12:22:32 /ip4/127.0.0.1/tcp/10000/ipfs/QmfRY4vuKpU2tApACrbmYFn9xoeNzMQhLXg7nKnyvnzHeL 2018/02/19 12:22:32 /ip4/192.168.1.203/tcp/10000/ipfs/QmfRY4vuKpU2tApACrbmYFn9xoeNzMQhLXg7nKnyvnzHeL 2018/02/19 12:22:32 Now run "./routed-echo -l 10001 -d QmfRY4vuKpU2tApACrbmYFn9xoeNzMQhLXg7nKnyvnzHeL" on a different terminal 2018/02/19 12:22:32 listening for connections
on the fourth line it says that the other has to run the Go code using a hash paramater that is given by the first node, but if the first node isn't connected to the second node, then how would that hash get passed? If we assume that the second node is new to the network they would have to know that session hash, which they don't because they aren't connected.
How would the second node discover the first if the second node is new to the network and has had no contact with that node prior to this moment.

@upperwal
Copy link
Contributor

When you ran ./routed-echo -l 10000 info about this node is stored on the DHT (Distributed Hash Table) and will be used to map node_hash to multiaddr.

On executing ./routed-echo -l 10001 -d QmfRY4vuKpU2tApACrbmYFn9xoeNzMQhLXg7nKnyvnzHeL, multiaddr corresponding to this hash is retrieved from the DHT which can be used to open a stream with this node.

@agahEbrahimi
Copy link

agahEbrahimi commented Apr 15, 2018

I get that part but if the person running the ./routed-echo -l 10001 -d QmfRY4vuKpU2tApACrbmYFn9xoeNzMQhLXg7nKnyvnzHeL has never initiated contact with the other node how does it get access to this address "QmfRY4vuKpU2tApACrbmYFn9xoeNzMQhLXg7nKnyvnzHeL"?
Would it be with the kad-dht? if yes, how would new identities/addresses be published to it?

@jiangsuwwj1
Copy link
Author

@upperwal how to construct a private bootstrapper node? If i don't want run the whole ipfs node. Is there any examples to do that?

@Stebalien
Copy link
Member

@jiangsuwwj1 there's a bootstrapping example here: #278

@jiangsuwwj1
Copy link
Author

@Stebalien Thank you very much, I will try later.

marten-seemann pushed a commit that referenced this issue Apr 21, 2022
release the stream scope if the conn fails to open a new stream
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

No branches or pull requests

4 participants