-
Notifications
You must be signed in to change notification settings - Fork 990
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
Listen for p2p connections on IPv6 (besides IPv4) #3208
Conversation
Thanks for your contribution! Can we add couple tests for the default config, eg test ipv4 and ipv6 clients? |
Thank you for your contribution @dagonharett, going to run some tests on macOS/Windows. In any case that's a simple yet very useful PR :) |
I had a feeling enabling IPv6 with Rust would be that simple. As mentioned above, some unit tests testing each interface would be appreciated. |
We are seeing some ipv4-mapped ipv6 addresses on the network currently and circumstantially we have noticed that peer behavior feels different on public nodes. |
Thank you all for the feedback! And sorry for the delay on my reply. As I've never programmed in Rust, I am pretty oblivious to where and how I should to create the unit tests. I would appreciate if someone experienced could step in and take this task. Anyway, I took a look into p2p/tests and it seems that I could re-use |
Hi @dagonharett, I haven't tried again since we changed several things on the node side. I think something like |
Listen for p2p connections on both IPv6 and IPv4 as default. Explain all the available options in the config file comments.
I've just pushed a commit that adds the IPv6 test (IPv4 was already there, I just had to do some minor refactoring). I opted to add the test into Unfortunately, the IPv6 test fails on macos in a way that I cannot reproduce on Linux: (I did a rebase to make sure no conflicting code had been introduced. This forced me to do a force push. Perhaps not the wisest decision.) |
I tested on OSX, it fails. The problem is not related to your change, you run the same code twice, it creates a p2p server with data folder |
@hashmap Thanks a lot for testing and for the suggestion. I've now replaced the static After this I added a new test,
Seems like things work a bit different when using the local host. Any idea on how to force the client to IPv4? Or should I just remove this test? |
I'm not sure it's specific to localhost and having this test is a good idea. The problem is here - https://github.com/mimblewimble/grin/blob/master/p2p/src/handshake.rs#L255 - we get an IPv4 addr as |
Reading again these lines of code. There is two parts in the code where we call this function:
In both case the At which point we take this Three questions here:
|
|
Thanks for the answer. Yeah I understand that if we listen on ipv4 then this will be an ipv4 mapped ivp6. Regarding 2 I was talking about doing something like that (untested code and doesn't change the logic at all...): /// Resolve the correct peer_addr based on the connection and the advertised port.
fn resolve_peer_addr(advertised: PeerAddr, conn: &TcpStream) -> PeerAddr {
let port = advertised.0.port();
if let Ok(mut addr) = conn.peer_addr() {
PeerAddr(addr.set_port(port));
} else {
advertised
}
} |
Wouldn’t it alter the existing incoming connection? Even if not the intention is less clear now. |
Bingo!
Thanks for taking a look at it.
@hashmap Makes sense. But poses a problem: how to translate the IP address? IPv6 to IPv4 translation would only work for localhost and IPv4 mapped IPv6. We would have to assume (and check) that we are in one of those scenarios. Actually, I cannot think of any other (non-malicious) scenario where the connection is IPv6 and advertised is IPv4. The code excerpt from @quentinlesceller above will not work due to the lack of this IP address translation. I run a test with a slightly modified version, that avoids modifying the incoming connection, as @hashmap suggested: fn resolve_peer_addr(advertised: PeerAddr, conn: &TcpStream) -> PeerAddr {
let port = advertised.0.port();
if let Ok(addr) = conn.peer_addr() {
let mut new_addr = addr.clone();
new_addr.set_port(port);
PeerAddr(new_addr)
} else {
advertised
}
} The
We would like it to save an IPv4 address ( Should I add some checks into |
Hi @dagonharett not sure if you are still around but I still think this would be very interesting to have this in Grin. I'll have a look again on your PR and see why tests are not passing. |
I took the liberty to merge the current master into your branch @dagonharett in order to debug the problem. Hope that's fine 😄 |
Hi @quentinlesceller sorry for the delay on my reply. Yes, I am still around and willing to get this done. |
Closed and marked as 'abandoned'. This does not mean the PR is unworthy. This means that merging it would require further work that nobody appears prepared to do at this time, or the original author has been unresponsive for a significant amount of time. Anyone who want to continue work on this functionality is free to re-open this at any time. |
This simple PR makes grin listen for p2p connections on both IPv6 and IPv4 as default. It also adds a summary of all the available options into the config file comments.
It's 2020 and IPv6 is now deployed throughout the world. We are now even getting to the point where some machines only have IPv6 connection. This happens already with several cloud providers that offer IPv6-only VPSes.
Seems wise to turn on IPv6 by default now. Otherwise, grin nodes running in IPv6-only environments will not be able to reach any peers. Also, as detailed on #461, IPv6 brings in other advantages like avoiding the need for NAT.
Fortunately grin already supports IPv6 out-of-the-box. By setting the listening address to
::
, the underlying Rust libraries set up a socket that listens both on IPv4 and IPv6.I tested this on several Linux machines (baremetal and VPS) and they successfully connected together with both IPv4 and IPv6. Would be nice if someone could test on Windows and macOS. Anyway, this should be more than safe now. We would have to go far into the past to find versions of these operating systems without an IPv6 stack.