Chord DHT response method - networking

I am building a Chord DHT in Go (however the language part isn't important).
And I am trying to figure out the response behavior between nodes. If I want to send a successor request message to Node C, but it has to go to Node A -> Node B first, then arriving at Node C. What is the best way for Node C to respond to the original Node.
I have come up with the distinct methods, but dont know which one is more idomatic for DHTs.
When each node makes a request, it waits for the response on the original TCP connection, this makes it so the response takes the reverse path it originally took
Make the request then forget about it, when Node C recieves the request it sends the response directly back to the original node, indicated by the sender (IPAddress) field in the request message.
Send the response to the sender NodeID just as it were any other message, so it would be routed around the Chord ring.
I cant figure out which is the best method to use.

The only reason you use routing in Chord, is to find resources. That's why you shouldn't just know the accessor and predecessor but also additional nodes in distances of 2^n. This way you can achieve a lookup performance of O(log N). You can read the Wikipedia article about Chord for details.
So you should attach to the message you are sending to Node C the source-node's address, so that C can respond directly. This will have a much better performance over all.

Related

Handling Race Conditions / Concurrency in Network Protocol Design

I am looking for possible techniques to gracefully handle race conditions in network protocol design. I find that in some cases, it is particularly hard to synchronize two nodes to enter a specific protocol state. Here is an example protocol with such a problem.
Let's say A and B are in an ESTABLISHED state and exchange data. All messages sent by A or B use a monotonically increasing sequence number, such that A can know the order of the messages sent by B, and A can know the order of the messages sent by B. At any time in this state, either A or B can send a ACTION_1 message to the other, in order to enter a different state where a strictly sequential exchange of message needs to happen:
send ACTION_1
recv ACTION_2
send ACTION_3
However, it is possible that both A and B send the ACTION_1 message at the same time, causing both of them to receive an ACTION_1 message, while they would expect to receive an ACTION_2 message as a result of sending ACTION_1.
Here are a few possible ways this could be handled:
1) change state after sending ACTION_1 to ACTION_1_SENT. If we receive ACTION_1 in this state, we detect the race condition, and proceed to arbitrate who gets to start the sequence. However, I have no idea how to fairly arbitrate this. Since both ends are likely going to detect the race condition at about the same time, any action that follows will be prone to other similar race conditions, such as sending ACTION_1 again.
2) Duplicate the entire sequence of messages. If we receive ACTION_1 in the ACTION_1_SENT state, we include the data of the other ACTION_1 message in the ACTION_2 message, etc. This can only work if there is no need to decide who is the "owner" of the action, since both ends will end up doing the same action to each other.
3) Use absolute time stamps, but then, accurate time synchronization is not an easy thing at all.
4) Use lamport clocks, but from what I understood these are only useful for events that are causally related. Since in this case the ACTION_1 messages are not causally related, I don't see how it could help solve the problem of figuring out which one happened first to discard the second one.
5) Use some predefined way of discarding one of the two messages on receipt by both ends. However, I cannot find a way to do this that is unflawed. A naive idea would be to include a random number on both sides, and select the message with the highest number as the "winner", discarding the one with the lowest number. However, we have a tie if both numbers are equal, and then we need another way to recover from this. A possible improvement would be to deal with arbitration once at connection time and repeat similar sequence until one of the two "wins", marking it as favourite. Every time a tie happens, the favourite wins.
Does anybody have further ideas on how to handle this?
EDIT:
Here is the current solution I came up with. Since I couldn't find 100% safe way to prevent ties, I decided to have my protocol elect a "favorite" during the connection sequence. Electing this favorite requires breaking possible ties, but in this case the protocol will allow for trying multiple times to elect the favorite until a consensus is reached. After the favorite is elected, all further ties are resolved by favoring the elected favorite. This isolates the problem of possible ties to a single part of the protocol.
As for fairness in the election process, I wrote something rather simple based on two values sent in each of the client/server packets. In this case, this number is a sequence number starting at a random value, but they could be anything as long as those numbers are fairly random to be fair.
When the client and server have to resolve a conflict, they both call this function with the send (their value) and the recv (the other value) values. The favorite calls this function with the favorite parameter set to TRUE. This function is guaranteed to give the opposite result on both ends, such that it is possible to break the tie without retransmitting a new message.
BOOL ResolveConflict(BOOL favorite, UINT32 sendVal, UINT32 recvVal)
{
BOOL winner;
int sendDiff;
int recvDiff;
UINT32 xorVal;
xorVal = sendVal ^ recvVal;
sendDiff = (xorVal < sendVal) ? sendVal - xorVal : xorVal - sendVal;
recvDiff = (xorVal < recvVal) ? recvVal - xorVal : xorVal - recvVal;
if (sendDiff != recvDiff)
winner = (sendDiff < recvDiff) ? TRUE : FALSE; /* closest value to xorVal wins */
else
winner = favorite; /* break tie, make favorite win */
return winner;
}
Let's say that both ends enter the ACTION_1_SENT state after sending the ACTION_1 message. Both will receive the ACTION_1 message in the ACTION_1_SENT state, but only one will win. The loser accepts the ACTION_1 message and enters the ACTION_1_RCVD state, while the winner discards the incoming ACTION_1 message. The rest of the sequence continues as if the loser had never sent ACTION_1 in a race condition with the winner.
Let me know what you think, and how this could be further improved.
To me, this whole idea that this ACTION_1 - ACTION_2 - ACTION_3 handshake must occur in sequence with no other message intervening is very onerous, and not at all in line with the reality of networks (or distributed systems in general). The complexity of some of your proposed solutions give reason to step back and rethink.
There are all kinds of complicating factors when dealing with systems distributed over a network: packets which don't arrive, arrive late, arrive out of order, arrive duplicated, clocks which are out of sync, clocks which go backwards sometimes, nodes which crash/reboot, etc. etc. You would like your protocol to be robust under any of these adverse conditions, and you would like to know with certainty that it is robust. That means making it simple enough that you can think through all the possible cases that may occur.
It also means abandoning the idea that there will always be "one true state" shared by all nodes, and the idea that you can make things happen in a very controlled, precise, "clockwork" sequence. You want to design for the case where the nodes do not agree on their shared state, and make the system self-healing under that condition. You also must assume that any possible message may occur in any order at all.
In this case, the problem is claiming "ownership" of a shared clipboard. Here's a basic question you need to think through first:
If all the nodes involved cannot communicate at some point in time, should a node which is trying to claim ownership just go ahead and behave as if it is the owner? (This means the system doesn't freeze when the network is down, but it means you will have multiple "owners" at times, and there will be divergent changes to the clipboard which have to be merged or otherwise "fixed up" later.)
Or, should no node ever assume it is the owner unless it receives confirmation from all other nodes? (This means the system will freeze sometimes, or just respond very slowly, but you will never have weird situations with divergent changes.)
If your answer is #1: don't focus so much on the protocol for claiming ownership. Come up with something simple which reduces the chances that two nodes will both become "owner" at the same time, but be very explicit that there can be more than one owner. Put more effort into the procedure for resolving divergence when it does happen. Think that part through extra carefully and make sure that the multiple owners will always converge. There should be no case where they can get stuck in an infinite loop trying to converge but failing.
If your answer is #2: here be dragons! You are trying to do something which buts up against some fundamental limitations.
Be very explicit that there is a state where a node is "seeking ownership", but has not obtained it yet.
When a node is seeking ownership, I would say that it should send a request to all other nodes, at intervals (in case another one misses the first request). Put a unique identifier on each such request, which is repeated in the reply (so delayed replies are not misinterpreted as applying to a request sent later).
To become owner, a node should receive a positive reply from all other nodes within a certain period of time. During that wait period, it should refuse to grant ownership to any other node. On the other hand, if a node has agreed to grant ownership to another node, it should not request ownership for another period of time (which must be somewhat longer).
If a node thinks it is owner, it should notify the others, and repeat the notification periodically.
You need to deal with the situation where two nodes both try to seek ownership at the same time, and both NAK (refuse ownership to) each other. You have to avoid a situation where they keep timing out, retrying, and then NAKing each other again (meaning that nobody would ever get ownership).
You could use exponential backoff, or you could make a simple tie-breaking rule (it doesn't have to be fair, since this should be a rare occurrence). Give each node a priority (you will have to figure out how to derive the priorities), and say that if a node which is seeking ownership receives a request for ownership from a higher-priority node, it will immediately stop seeking ownership and grant it to the high-priority node instead.
This will not result in more than one node becoming owner, because if the high-priority node had previously ACKed the request sent by the low-priority node, it would not send a request of its own until enough time had passed that it was sure its previous ACK was no longer valid.
You also have to consider what happens if a node becomes owner, and then "goes dark" -- stops responding. At what point are other nodes allowed to assume that ownership is "up for grabs" again? This is a very sticky issue, and I suspect you will not find any solution which eliminates the possibility of having multiple owners at the same time.
Probably, all the nodes will need to "ping" each other from time to time. (Not referring to an ICMP echo, but something built in to your own protocol.) If the clipboard owner can't reach the others for some period of time, it must assume that it is no longer owner. And if the others can't reach the owner for a longer period of time, they can assume that ownership is available and can be requested.
Here is a simplified answer for the protocol of interest here.
In this case, there is only a client and a server, communicating over TCP. The goal of the protocol is to two system clipboards. The regular state when outside of a particular sequence is simply "CLIPBOARD_ESTABLISHED".
Whenever one of the two systems pastes something onto its clipboard, it sends a ClipboardFormatListReq message, and transitions to the CLIPBOARD_FORMAT_LIST_REQ_SENT state. This message contains a sequence number that is incremented when sending the ClipboardFormatListReq message. Under normal circumstances, no race condition occurs and a ClipboardFormatListRsp message is sent back to acknowledge the new sequence number and owner. The list contained in the request is used to expose clipboard data formats offered by the owner, and any of these formats can be requested by an application on the remote system.
When an application requests one of the data formats from the clipboard owner, a ClipboardFormatDataReq message is sent with the sequence number, and format id from the list, the state is changed to CLIPBOARD_FORMAT_DATA_REQ_SENT. Under normal circumstances, there is no change of clipboard ownership during that time, and the data is returned in the ClipboardFormatDataRsp message. A timer should be used to timeout if no response is sent fast enough from the other system, and abort the sequence if it takes too long.
Now, for the special cases:
If we receive ClipboardFormatListReq in the CLIPBOARD_FORMAT_LIST_REQ_SENT state, it means both systems are trying to gain ownership at the same time. Only one owner should be selected, in this case, we can keep it simple an elect the client as the default winner. With the client as the default owner, the server should respond to the client with ClipboardFormatListRsp consider the client as the new owner.
If we receive ClipboardFormatDataReq in the CLIPBOARD_FORMAT_LIST_REQ_SENT state, it means we have just received a request for data from the previous list of data formats, since we have just sent a request to become the new owner with a new list of data formats. We can respond with a failure right away, and sequence numbers will not match.
Etc, etc. The main issue I was trying to solve here is fast recovery from such states, with going into a loop of retrying until it works. The main issue with immediate retrial is that it is going to happen with timing likely to cause new race conditions. We can solve the issue by expecting such inconsistent states as long as we can move back to proper protocol states when detecting them. The other part of the problem is with electing a "winner" that will have its request accepted without resending new messages. A default winner can be elected by default, such as the client or the server, or some sort of random voting system can be implemented with a default favorite to break ties.

How to minimize the flooding of RREQ packet in AODV if an intermediate node has replied the source with the path?

Suppose we have a condition in AODV protocol
RREQ(route request) packet in AODV(MANET protocol) goes on moving to the destination even if a node at TTL=1 has replied for the route request.For example,n1,n2 and n3 are 3 nodes at TTL=1 and n2 replies to source S but n1 and n3 have rebroadcasted the RREQ packet towards destination D which would perhaps create unnecessary flooding in the network . Now I thought a naive solution to minimize this flooding that n2 will also broadcast another packet containing information that it has replied to the RREQ for S to D probably using something like a higher Destination sequence number in it or containing the same Broadcast ID as the RREQ. But what it will do is create another chance of flooding . So,are there any possible ways by which we could minimize this problem in a more effective manner?NOTE:AODV is a reactive routing protocol in Mobile Ad-Hoc network systems which rely on table routing .
This is a research topic. There are several solutions provided for the same. On of the efficient solution is provided as:
Source node starts broadcasting for the first time with a small TTL value of 1. This RREQ reaches adjacent nodes, they checks weather they contain an updated route for the destination. Those having an updated route for the destination replies with RREP and rest of the nodes can't rebroadcast because TTL is expired. If no one has the route, the RREQ is rebroadcasted by source with one increased value of TTL=2. This way, RREQ packet is rebroadcasted only when the nodes do not have path for the destination.
This method also increases flooding of RREQ packets but it is an optimization problem, still it is one of the good method to solve this problem.
Hope its clear now.
The Condition Of node in Aodv protocol is just check the receiving packet type, if its RREQ means just forward to all of its neighbours .if u want to minimize RREQ u can add your condition in Recvpacket() functions.better is u can use number of hops to create a new condition.

Omnet++: Simultaneously send messages from more than one node

I want to animate a node receiving messages from three different nodes in OMNET++. Right now the nodes send in a sequential manner. But, I want the nodes to send messages to the root node simultaneously. Root node is occupied with an array of input gates. Is it possible in Omnet?
You can configure the 3 nodes to send the messages at the same time by scheduling messages to be sent at the same time using the scheduleAt() function. The simulation will always show that they are transmitted sequentially, but check the T (event time) value in the simulation window. If the T value is the same every time any of the 3 messages are being sent, it means they are sent simultaneously.
The messages arriving to the root node can't be processed at the same time. Every node, including the root node, implements the handleMessage() function which will analyze each incoming message individually.
I hope this is the answer you were looking for.
You have to define parameter id in ned file. In initialize set the condition if(getIndex==id), send the message. Same message will be send to the node simultaneously.

Understanding how to manage message routing direction in P2P Chord/Pastry-like networks

This is a question about a large scalable P2P networking approach: logical ring net ovrlay.
Consider the context of P2P networking. There are N computers that are connected everyone to each other through a ring.
Every node has a routing table memorizing the predecessor and the successor node.
This is the simplest case when routing tables store only a predecessor and a successor.
Every node is provided with an id which is a number.
The ring is organized so that ascending numbers are assigned in clockwose direction.
So we can have a situation like this: * - 12 - 13 - 45 - 55 - 180 - 255 - *
This network has 6 nodes and they are connected in circle.
When a node must send a message to another node, the routing tables are used, if the generic node has an incoming message, it looks at the dest address and, if not in his routing table, the successor or predecesor will be up to route it.
Now let's consider this example.
In my simple network, node 13 wants to send a message to node 255.
Since every node can see only a predecessor and a successor, every node is not able to consider the global network, in P2P, in fact, a node can see only a part of the net. So node 13 has a decision to take: where to route the message (since the destination is not in its neighbourhood)? Does the message have to be sent to 45 or to 12? (clockwise or counterclockwise?).
Well, obviously, sending to 12 is a better decision, but how is node 13 able to know this?
The simplest solution would be: always route clockwise, but in this case a very near node will be reached in so much time..... while it was behind the corner....
How to handle this?
PS:
There are solution like Fingering applied to clockwise routing based approaches.
Fingering puts in routing table other addresses in order to create jump links...
This is a solution that can be used but with clockwise routing only...
http://en.wikipedia.org/wiki/File:Chord_route.png
I would like to know a good solution in order to find the right routing direction... does it exist? How does Chord handle this?
Thank you.
If every node remember link to the next one, the second one, the fourth one, the eighth one, and so on, then it takes only log(n) time to find any node. I believe that this is fast enough to not consider if you should go cw or ccw.

Edge direction in network diagrams

When I draw a network diagram with, say, browser A communicates with http-server B which talks to a database C, I draw the nodes for A, B and C and edges between A and B and between B and C. Then I want to materialize the flow direction by adding arrows. On which side should I place the arrowheads?
alt text http://www.forteresse.net/site/stack-overflow-question/image
Variant 2 is the intuitive one, but IMHO, the variant 1 is the correct one since the data is really flowing from B towards A.
I want to indicate that the browser is accessing the http-server for reading a web page, for example A is browsing http://www.xyz.com
So, are there any references to help me on this?
If it's a diagram of "what the user is doing", the user is going from client to server.
If it's a diagram of "where data is going", the client is passing a string to the server, and the server is returning a string to the client; it can be a two way arrow.
I'd probably go with Variant 1. "The browser is accessing" is a one-way operation.
When you want to indicate that data is sent from (Client)A to (Server)B, draw the arrow from A to B. When you want to indicate that data is sent from (Server)B back to (Client)A, draw the arrow from B to A. Data can flow both ways.
In regards to your slashdot reference, when the (Client)A wants to browse to Slashdot.org, it makes a request to the server, so you would draw an arrow from (Client)A to (Server)Slashdot.org. When Slashdot receives this request, it sends back a response to your client to render Slashdot in your browser, so in that case you would draw an arrow from Server(Slashdot.org) to (Client)A.
Here is a simple reference explaining it:
http://computer.howstuffworks.com/web-server1.htm

Resources