-
Notifications
You must be signed in to change notification settings - Fork 5
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
Seed node not adding details of connecting node to its NodeGraph
#344
Comments
Going back to the Kademlia protocol, we have the following about new nodes joining the network from the original research paper https://www.scs.stanford.edu/~dm/home/papers/kpos.pdf:
And on "refreshing":
We don't currently have this notion of "refreshing", nor do we perform this refresh when a node enters the network. Given that we connect to an initial seed node on bootstrapping, we have a different kind of "refreshing"/synchronisation process to initially populate their database:
However, this discussion's important part: During the refreshes, This brings up an interesting point: when a node wants to add some other When a node "found" a new node ID pointing to some host and port, our initial implementation of Kademlia required a connection to be established to that node, such that we could verify that this node ID and host/port was valid. This has since been removed though, and we'll be looking at a different means of doing this in #322. Because this connection establishment was required though, we could have used a similar approach to what we'll be implementing with the seed node: on connection establishment, we should automatically add this connecting node to our |
My concluding point from the above is basically that we should be generalising this for all nodes (and not just seed nodes). When a node connects to any node in the Polykey network, the other node should be adding the connecting node to its own Therefore, we'd have the following means of the
|
For generalising this to all nodes, that's easy enough. Given that we require hole punching for a connection to be established between two arbitrary keynodes, we can push this
The first option makes the most sense to me, given that it's directly in the nodes domain instead of right at the boundary. However, the seed nodes are a special case. The seed nodes are not expected to be behind a NAT, thus require no hole-punching or any intervention on their part to support a node's connection establishment. So, what program logic can we link this into? The lower level networking? |
This sounds like a server side interceptor problem. We don't have server side interceptor available unfortunately and @tegefaulkes needs it for acquiring authentic connecting node information in #342. Yes this could have been done at the lower level involving network domain like optimising the ping command to just use UTP instead of going all the way to GRPC. Basically node A must connect to node B somehow and trigger node B to add node A to its DHT. Did you check other implementations if they do this? |
Referencing kademlia paper and kademlia wikipedia page:
The key sentence is The "self-lookup" will populate other nodes' k-buckets with the new node ID, and will populate the joining node's k-buckets with the nodes in the path between it and the bootstrap node. The refreshing logic discussed later is a separate problem and would need to be a new issue. That's about keeping the nodegraph up to date and would be triggered on max-TTLs of a bucket and when joining the network. So the look up procedure right now involves agent to agent communication, Node A will call
It is during the handler where the Node B needs to add Node A to its own node graph. But it is not just done on Node B, this is done on every node that Node A calls For example, with Node A, Seed Node and Node B. https://excalidraw.com/#json=CupwHTnu8UN6SmhTiUV8C,OtRF9UZIbSd9x1UurmV-bA The process is actually doable on any node, not just seed nodes. Adding Node A to any node graph requires Node A's ingress host and ingress port. For example, assume Node A and Node B. Node A's ingress host and ingress port information is not "naturally" part of any request sent from Node A to Node B. This is due to our network design. The original kademlia design was based on UDP. And in UDP, you can send and receive UDP packets on the same port number. Therefore upon receiving a lookup request in UDP, you could just add the host and port directly into the node graph. However this is not the case with our system. In our network design, not only do we have proxies that are doing TLS termination, Node A's ingress host and ingress port is not on the
And as you can see the And while the Node A's
And you can see that the ports are not the same. Note that using There may be a possibility that Node A's If the 2 ports need to be different, then the solution is to add Node A's |
From discussions today, two main things that need to be addressed: 1. Adding a node to another node's
|
If the ports can be the same, it would be simplest solution, so to try this. I need to go into await this.fwdProxy.start({
proxyHost: networkConfig_.proxyHost,
proxyPort: networkConfig_.proxyPort,
egressHost: networkConfig_.egressHost,
egressPort: networkConfig_.egressPort,
tlsConfig,
});
await this.revProxy.start({
serverHost: this.grpcServerAgent.host,
serverPort: this.grpcServerAgent.port,
ingressHost: networkConfig_.ingressHost,
ingressPort: networkConfig_.ingressPort,
tlsConfig,
}); Into this: await this.revProxy.start({
serverHost: this.grpcServerAgent.host,
serverPort: this.grpcServerAgent.port,
ingressHost: networkConfig_.ingressHost,
ingressPort: networkConfig_.ingressPort,
tlsConfig,
});
await this.fwdProxy.start({
proxyHost: networkConfig_.proxyHost,
proxyPort: networkConfig_.proxyPort,
egressHost: this.revProxy.getIngressHost(),
egressPort: this.revProxy.getIngressPort(),
tlsConfig,
}); Just tried, it doesn't work. If you try to use the same port for both ingress and egress, you get an Reminder: Add this possible exception to the possible |
Ok so this means that we need to have This wouldn't even be solved with having the reverse proxy be capable of inspecting GRPC frames. So I guess GRPC metadata is the only foolproof solution here. We have to deal with when the metadata is not there, and then fail the request. We can add a client side interceptor on our Furthermore, the data received on the server side may be incorrect or spoofed. However this is the same problem as DHT poisoning #226 and #150, since any node can store invalid DHT records and present them. Possibly the same problem as relayed requests. Basically no guarantee that the node graph entries are correct. I suppose that's where the node bucket refreshing system can help. |
Also another reasonable resource for understanding Kademlia process https://stackoverflow.com/questions/19329682/adding-new-nodes-to-kademlia-building-kademlia-routing-tables |
This will need ETAed, as it is the main blocker for #326. |
Refactoring the Any flexibility could only happen by auto-expanding the node id bit size when the node ids get larger. But if the node ids get smaller than the buckets would need to be re-laid out. Therefore it makes more sense to have the key size specified ahead of time in the node graph creation, and later have a migration process if the key size were to change. |
This issue can be expanded to generally deal with any policies to add new nodes into the NodeGraph compared to #266 which is about dealing generally with removing nodes from the NodeGraph. |
Suppose N1 connects to N2. How does N2 add N1 to it's NodeGraph? Currently we do not have access to server side interceptors. This is why we created all those utility functions in And even if we were to create the utility function, it would only work when a GRPC call is made, not just when a connection is established. So if we want to do this as soon as a connection has been established, then the only 2 places that executes code here would be:
If you are going through the proxy, the verification of the client certificate is on the So there are 2 ways we can implement this:
Since we already have the events system available, we might as well use it. Also |
N1 would already N2's information by the time it contacts through the However the failure could occur in different ways:
If But because all of this would happen in the nodes domain, it seems like any callback to the |
I'm trying to spec out the solution for this. I've run into some problems I'm still trying to solve. So the core of the problem is that we need to authenticate an incoming connection to check if it is a valid node and obtain the The problem is. we can't know this until a connection is started. a port for the reverse proxy doesn't exist until a connection is started by the reverse proxy. Only then is the port for it created on the So it seems getting the port information and storing it in the SO it seems that for most cases we only need to store the In the case where we can establish a direct connection without using the There is something bothering me with how the |
with #360 being merged into master we should be able to continue this now. |
Added a callback to the `Proxy` that is called when a `ForwardConnection` or `ReverseConnection` is established and authenticated. It is called with the following connection information; `remoteNodeId`, `remoteHost`, `remotePort` and `type`. They type signifies if it was a forward or reverse connection. Note that this is only triggered by composed connections. Added a test for if the callback was called when a `ReverseConnection` is established. Relates #332 Relates #344
Added a callback to the `Proxy` that is called when a `ForwardConnection` or `ReverseConnection` is established and authenticated. It is called with the following connection information; `remoteNodeId`, `remoteHost`, `remotePort` and `type`. They type signifies if it was a forward or reverse connection. Note that this is only triggered by composed connections. Added a test for if the callback was called when a `ReverseConnection` is established. Relates #332 Relates #344
Added an event to the `EventBus` that is triggered by the `Proxy`'s `connectionEstablishedCallback`. this adds the node to the `NodeGraph`. Related #344
Added a callback to the `Proxy` that is called when a `ForwardConnection` or `ReverseConnection` is established and authenticated. It is called with the following connection information; `remoteNodeId`, `remoteHost`, `remotePort` and `type`. They type signifies if it was a forward or reverse connection. Note that this is only triggered by composed connections. Added a test for if the callback was called when a `ReverseConnection` is established. Relates #332 Relates #344
Added an event to the `EventBus` that is triggered by the `Proxy`'s `connectionEstablishedCallback`. this adds the node to the `NodeGraph`. Related #344
Added a callback to the `Proxy` that is called when a `ForwardConnection` or `ReverseConnection` is established and authenticated. It is called with the following connection information; `remoteNodeId`, `remoteHost`, `remotePort` and `type`. They type signifies if it was a forward or reverse connection. Note that this is only triggered by composed connections. Added a test for if the callback was called when a `ReverseConnection` is established. Relates #332 Relates #344
Added an event to the `EventBus` that is triggered by the `Proxy`'s `connectionEstablishedCallback`. this adds the node to the `NodeGraph`. Related #344
Added a callback to the `Proxy` that is called when a `ForwardConnection` or `ReverseConnection` is established and authenticated. It is called with the following connection information; `remoteNodeId`, `remoteHost`, `remotePort` and `type`. They type signifies if it was a forward or reverse connection. Note that this is only triggered by composed connections. Added a test for if the callback was called when a `ReverseConnection` is established. Relates #332 Relates #344
Added an event to the `EventBus` that is triggered by the `Proxy`'s `connectionEstablishedCallback`. this adds the node to the `NodeGraph`. Related #344
Added a callback to the `Proxy` that is called when a `ForwardConnection` or `ReverseConnection` is established and authenticated. It is called with the following connection information; `remoteNodeId`, `remoteHost`, `remotePort` and `type`. They type signifies if it was a forward or reverse connection. Note that this is only triggered by composed connections. Added a test for if the callback was called when a `ReverseConnection` is established. Relates #332 Relates #344
Added an event to the `EventBus` that is triggered by the `Proxy`'s `connectionEstablishedCallback`. this adds the node to the `NodeGraph`. Related #344
Added a callback to the `Proxy` that is called when a `ForwardConnection` or `ReverseConnection` is established and authenticated. It is called with the following connection information; `remoteNodeId`, `remoteHost`, `remotePort` and `type`. They type signifies if it was a forward or reverse connection. Note that this is only triggered by composed connections. Added a test for if the callback was called when a `ReverseConnection` is established. Relates #332 Relates #344
Added an event to the `EventBus` that is triggered by the `Proxy`'s `connectionEstablishedCallback`. this adds the node to the `NodeGraph`. Related #344
Added a callback to the `Proxy` that is called when a `ForwardConnection` or `ReverseConnection` is established and authenticated. It is called with the following connection information; `remoteNodeId`, `remoteHost`, `remotePort` and `type`. They type signifies if it was a forward or reverse connection. Note that this is only triggered by composed connections. Added a test for if the callback was called when a `ReverseConnection` is established. Relates #332 Relates #344
Added an event to the `EventBus` that is triggered by the `Proxy`'s `connectionEstablishedCallback`. this adds the node to the `NodeGraph`. Related #344
Added a callback to the `Proxy` that is called when a `ForwardConnection` or `ReverseConnection` is established and authenticated. It is called with the following connection information; `remoteNodeId`, `remoteHost`, `remotePort` and `type`. They type signifies if it was a forward or reverse connection. Note that this is only triggered by composed connections. Added a test for if the callback was called when a `ReverseConnection` is established. Relates #332 Relates #344
Added an event to the `EventBus` that is triggered by the `Proxy`'s `connectionEstablishedCallback`. this adds the node to the `NodeGraph`. Related #344
Added a callback to the `Proxy` that is called when a `ForwardConnection` or `ReverseConnection` is established and authenticated. It is called with the following connection information; `remoteNodeId`, `remoteHost`, `remotePort` and `type`. They type signifies if it was a forward or reverse connection. Note that this is only triggered by composed connections. Added a test for if the callback was called when a `ReverseConnection` is established. Relates #332 Relates #344
Added an event to the `EventBus` that is triggered by the `Proxy`'s `connectionEstablishedCallback`. this adds the node to the `NodeGraph`. Related #344
Added a callback to the `Proxy` that is called when a `ForwardConnection` or `ReverseConnection` is established and authenticated. It is called with the following connection information; `remoteNodeId`, `remoteHost`, `remotePort` and `type`. They type signifies if it was a forward or reverse connection. Note that this is only triggered by composed connections. Added a test for if the callback was called when a `ReverseConnection` is established. Relates #332 Relates #344
Added an event to the `EventBus` that is triggered by the `Proxy`'s `connectionEstablishedCallback`. this adds the node to the `NodeGraph`. Related #344
Added a callback to the `Proxy` that is called when a `ForwardConnection` or `ReverseConnection` is established and authenticated. It is called with the following connection information; `remoteNodeId`, `remoteHost`, `remotePort` and `type`. They type signifies if it was a forward or reverse connection. Note that this is only triggered by composed connections. Added a test for if the callback was called when a `ReverseConnection` is established. Relates #332 Relates #344
Added an event to the `EventBus` that is triggered by the `Proxy`'s `connectionEstablishedCallback`. this adds the node to the `NodeGraph`. Related #344
Added a callback to the `Proxy` that is called when a `ForwardConnection` or `ReverseConnection` is established and authenticated. It is called with the following connection information; `remoteNodeId`, `remoteHost`, `remotePort` and `type`. They type signifies if it was a forward or reverse connection. Note that this is only triggered by composed connections. Added a test for if the callback was called when a `ReverseConnection` is established. Relates #332 Relates #344
Added an event to the `EventBus` that is triggered by the `Proxy`'s `connectionEstablishedCallback`. this adds the node to the `NodeGraph`. Related #344
I'm going to assume this is done. @tegefaulkes please check the last comment #344 (comment) and reopen if not. |
Added a callback to the `Proxy` that is called when a `ForwardConnection` or `ReverseConnection` is established and authenticated. It is called with the following connection information; `remoteNodeId`, `remoteHost`, `remotePort` and `type`. They type signifies if it was a forward or reverse connection. Note that this is only triggered by composed connections. Added a test for if the callback was called when a `ReverseConnection` is established. Relates #332 Relates #344
Added an event to the `EventBus` that is triggered by the `Proxy`'s `connectionEstablishedCallback`. this adds the node to the `NodeGraph`. Related #344
Specification
Authentication a node on the other side of a connection is done buy the
Proxy
class when a connection is made. This includes obtaining theNodeId
, certificates and connection info. I assume that the certificates are authenticated at this stage. This is all the information that we need to authenticate and add a node to the node graph with the added benefit of it being obtained at the time a connection is established.We need to add a callback to the
Proxy
that is triggered with theNodeId
,remoteHost
andremotePort
information whenever a connection is made. For simplicity this will be triggered when aForwardConnection
andReverseConnection
is made. SoProxy
needs to take a(remoteNodeId, remoteHost, remotePort) => void
callback that is triggered whenever a connection is established and authenticated.A new event needs to be added to the
EventBus
for this connection event. The handler for this event needs to callNodeManager.setNode()
to add the information to the nodeGraph.Additional context
ForwardProxy
andReverseProxy
intoProxy
#361. Changes affect this.KeyManager
#312 CLI and Client & Agent Service test splitting #311 ? I'm not sure where it was implemented.Tasks
connectionEstablishedCallback
to theProxy
that is triggered whenever a connection is authenticated and established.events
EventBus
in thePolykeyAgent
and have this triggered by the callback.NodeManager.setNode()
method thus adding the node to the nodeGraph.PolykeyAgent
to check that the event properly propagates and updates theNodeGraph
.The text was updated successfully, but these errors were encountered: