implementing ack over UDP?

ron picture ron · Oct 3, 2009 · Viewed 9.9k times · Source

We have a system (built in C) in place that performs communication over UDP. Recently we have found a necessity to guarantee delivery of packets. My question is: what would be the minimum additions to a UDP based system to ensure delivery using ack packets? Also, ideally without having to manipulate the packet headers. We have application level control over the packets including sequence numbers and ack/nack flags. I am wondering if this is a lost cause and anything we attempt to do will basically be a flawed and broken version of TCP. Basically, is there a minimalist improvement we can make to achieve guaranteed delivery (we do not need many features of TCP such as congestion control etc.). Thanks!

Answer

poundifdef picture poundifdef · Oct 4, 2009

TCP intertwines 3 services that might be relevant (okay TCP does a lot more, but I'm only going to talk about 3.)

  1. In-order delivery
  2. Reliable delivery
  3. Flow control

You just said that you don't need flow control, so I won't even address that (how you would advertise a window size, etc. well, except that you'll probably need a window. i'll get to it.)

You did say that you need reliable delivery. That isn't too hard - you use ACKs to show that the sender has received a packet. Basic reliable delivery looks like:

  1. Sender sends the packet
  2. Receiver receives packet, and then sends an ack
  3. If the sender doesn't get an ack (by way of a timer), he resends the packet.

Those three steps don't address these issues:

  1. What if the ACK gets lost?
  2. What if packets arrive out of order?

So for your application, you said you only needed reliable delivery - but didn't say anything about needing them in order. This will affect the way you implement your protocol.

(example where in-order doesn't matter: you're copying employee records from one computer to another. doesn't matter if Alice's record is received before Bob's, as long as both get there.)

So going on the presumption that you only need reliable (since that's what you said in your post), you could achieve this several ways.

Your sender can keep track of unacknowledged packets. So if it sends # 3, 4, 5, and 6, and doesn't get an ACK for 3 and 4, then the sender knows that it needs to retransmit. (Though the sender doesn't know if packets 3 and 4 were lots, or if their ACKs were lost. Either way, we have to retransmit.)

But then your sender could do cumulative ACKs - so in the above example, it would only ack #6 if it had received 3, 4, and 5. This means that the receiver would drop packet 6 if it hadn't received the ones before. If your network is very reliable, then this might not be a bad option.

The protocols described above, however, do have a window - that is, how many packets does the sender send at once? Which means that you do need some sort of windowing, but not for the purpose of flow control. How'll you transmit window sizes?

You could do it without a window by either having the window size constant, or by doing something like stop-and-wait. The former might be a better option.

Anyway, I haven't directly answered your question, but I hope I've pointed out some of the things that are worth considering when architecting this. The task of having "reliable transfer" without parts of flow control (like windowing) and without any regard to in-order is hard! (Let me know if I should give more details about some of this stuff!)

Good luck!