-
Notifications
You must be signed in to change notification settings - Fork 61
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
fix: preventing IP 0.0.0.0 from being published #1982
Conversation
You can find the image built from this PR at
Built from 6d34228 |
Note: publishing
If there is no canonical libp2p way to handle this (not aware of any atm), I'd use |
You can find the experimental image built from this PR at
Built from 6d34228 |
f781669
to
7772e87
Compare
@@ -121,6 +121,7 @@ proc addPeer*(pm: PeerManager, remotePeerInfo: RemotePeerInfo, origin = UnknownO | |||
discard remotePeerInfo.peerId.extractPublicKey(publicKey) | |||
|
|||
if pm.peerStore[AddressBook][remotePeerInfo.peerId] == remotePeerInfo.addrs and | |||
not ($remotePeerInfo.addrs).contains("127.0.0.1") and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you explain why this is needed, please? I cannot wrap my head around it, sorry:D
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes! So we were having issues with the peer exchange tests in which we weren't able to add peers when running locally after the initial change we made. pm.peerStore[AddressBook][remotePeerInfo.peerId]
equals 127.0.0.1
in local runs, and remotePeerInfo.addrs
used to equal 0.0.0.0
but after our fix to the Identify message, it equals 127.0.0.1
.
Because this if statement was always yielding true, it considered the IP 127.0.0.1
as duplicate, returned early from the addPeer procedure and we weren't able to add local peers. So we added a special case to bypass that check when it comes to localhost.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But that is strange, isn't it? We are also checking the publicKey, so that would mean that not only the address is the loopback interface, but also the pubKey is the same - IOW this check should be fals if you have multiple local node peers as long as they have different peerId, so the explicit check for 127.0.0.1 should not be necessary. Or I am still missing something:D
Can you share which tests were failing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that I look further into it I agree that there's something weird in there.
Maybe the public key check is reduntant/wrong? If pm.peerStore[KeyBook][remotePeerInfo.peerId]
has to have the value of the public key for a peerId, and publicKey
is a variable with the public key of the peer we are checking - aren't they supposed to be always the same?
The test that fails without that line is nwaku/tests/test_waku_peer_exchange test 'retrieve and provide peer exchange peers from discv5'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it would probably make sense to check that the remotePeerInfo.peerId
is a key in the KeyBook
, but checking the match with publicKey
does not really add value, since the peerId is (AFAIU) directly derived from publicKey
, so it will be always true as long as the key exists (which we already verify by the first check for AddressBook
, IMO).
Now the question is why does it not work without the check for loopback..
Since the peerId should be unique we should get false
from the AddressBook
check when first seeing the new node regardless of which addresses it advertises.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Weird, I commented out this line and ran the test you mentioned locall and everything passed:)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exactly! I'll take a deeper look on what's going on with the AddressBook
check.
In my test runs pm.peerStore[KeyBook][remotePeerInfo.peerId]
were always returning 127.0.0.1
, but if we are adding a new peer there shouldn't be an address assigned to it on the AddressBook
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Weird, I commented out this line and ran the test you mentioned locall and everything passed:)
That's really weird, without that line I couldn't get the test to pass neither locally nor in the CI. I'll DM you to have a look :)
Unsure I undestand why we want to advertise 127.0.0.1? If no |
@alrevuelta just to give some background: this only addresses the marginal case where no external IP of the node was configured or could be determined in any other way (NAT-PMP, UPnP, 3rd party, etc.). In other words, it really only affects the case where you are running node(s) locally. The issue was that you would then wrongly advertise the default
The reason for going with (2) is that it fixes the bug - i.e. undefined behaviour when including a zero IP in |
Labeled the PR again as draft, as it is still WIP. We're investigating why the following test is not passing without the exception for the the loopback address: https://github.com/waku-org/nwaku/blob/master/tests/test_waku_peer_exchange.nim#L74-L194 |
The proper way to do this is to use an addressMapper that would remove every addresses whos IP is 0.0.0.0, I think |
We tried the approach of using an addressMapper to remove every |
96ab7e8
to
013dd5a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approach lgtm now. :) Feel free to mark as ready for review when you feel it's mergeable and I'll do a full review, but should be an approve.
pm.peerStore[KeyBook][remotePeerInfo.peerId] == publicKey: | ||
# Peer already managed | ||
pm.peerStore[KeyBook][remotePeerInfo.peerId] == publicKey and | ||
pm.peerStore[ENRBook][remotePeerInfo.peerId].raw.len > 0: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, could you add a comment (to the issue, not the code) on why this is necessary? Is this because these peers were explicitly connected to in addition to being added via discovery?
The issue found was the following: We are calling With the new fix, if we call Why did it work before? Out of luck it seems. After changing the published IP to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
The only question I have is unrelated, why do we call addPeer()
twice?
I'm looking into it...
According to stack traces I added, the calls come from the functions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Thanks for it!
|
||
import | ||
stew/shims/net as stewNet, | ||
std/[strutils], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor nitpick
std/[strutils], | |
std/strutils, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done! Thank you! :)
013dd5a
to
6788709
Compare
LGTM! Well done. :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lgtm! Good job, sir!
6788709
to
33769b1
Compare
Description
Currently, the IP address
0.0.0.0
is being published in the Identify message when there's no external addresses found. This happens in cases when Waku nodes are being run locally.This goes against RFC 1122, section 3.2.1.3 where referring to the
0.0.0.0
IP it states:In that case, we will publish localhost's loopback interface's address
127.0.0.1
instead.Changes
formatListenAddress
, which checks if IP0.0.0.0
is present in the node's published address and if so, replaces it for127.0.0.1
.addPeer
to modify an existing peer entry whenever it's missing ENR data0.0.0.0
to use IP127.0.0.1
How to test
When running the node locally, if no IP address is specified (or if the 0 IP is provided as an input), the node should publish the
127.0.0.1
IP instead.If a custom IP is provided, it should be published
Issue
closes #1427