views:

299

answers:

3

Hello,

Say I've got a client-side counter variable. When I send a request to the server, I send this variable's value, then increment it by one (for the next request to the server). The server keeps track of this counter independantly, and checks to make sure that the count sent by the client is 1 more than it's own (server-side) copy of the count. This is all fine and dandy, but consider the following situation:

  1. The client sends, say, 23 to the server.
  2. The server receives 23, validates it, and increments its own counter to 23.
  3. The server returns the All-Okay code to the client

-BUT-

Along the way from the server to the client, the return code gets corrupted. The client thus thinks that the server did not update its counter, and so leaves the client-side counter at 23. From this point onwards, the client and server are out of sync.

Does anybody know any robust schemes that would work in the face of such possible corruption/errors?

Thanks,
Cameron

+1  A: 

The easy answer is to make one of the client or server the owner of the resource, instead of making both own its own copy of the resource.

If you're using a reliable protocol like TCP though, you don't have to worry about the message not getting to the client.

A good thing to follow when doing client/server work though is to make all operations idempotent. That is to say each function could be called one or many times without any side effects. In this case you wouldn't have an 'increment' function at all. Instead you'd have a 'set' function.

Brian R. Bondy
+2  A: 

Instead of using a linearly increasing counter, you can use a random "nonce" value of a good 64 bits of entropy or more. When the server receives a request from the client, the server checks to see whether the nonce matches the last one it sent the client. If so, then the request is processed and the server generates a new random nonce value to send in the response.

The server can keep the last two nonce values to send to the client. If the client sends the old value, then the server assumes that the most recent message to the client might have been lost.

The above method assumes that your goal is to prevent two different clients from using the same credentials to communicate with the server. The advantage of using the nonce method is that the next value can't easily be predicted.

Greg Hewgill
Yes, that is my goal, but the predictability of the number wouldn't have been an issue in my specific case. I did think of the nonce thing, but in a completely different direction; You're solution is very clean and fast. Thanks!
Cameron
+1  A: 

How about just not having the client update its local copy until the server acknowledges the update of the server counter.

So:

Client calculates next value Client sends next value to server Server checks that next value is valid (not already seen) Server updates counter to next value (if needed) Server notifies client that next value has been received Client updates local counter to next value

If the server does not receive the client update, the client merely resends the calculated next value. If the client does not receive the next value confirmation, it will resend the next value, but the server having already seen it does not update, but merely acknowledges. Eventually, the client sees the server's message and continues. This covers the case of lost messages.

If you are concerned about corruption, calculate a checksum on the message and send that as well. Recalculate the checksum on receipt and compare it to the one sent. Generally the network stack does this for you, though, so I wouldn't worry too much about it unless your are running your own protocol.

tvanfosson