Android Question UDP Checksum

Philip Prins

Active Member
Licensed User
Longtime User
Hello ,

I need to calculate the checksum according to this:
Checksum computation. The method used to compute the checksum is defined in RFC 768: Checksum is the 16-bit one's complement of the one's complement sum of a pseudo header of information from the IP header, the UDP header, and the data, padded with zero octets at the end (if necessary) to make a multiple of two octets.

I have this code:
C++:
uint16_t Sys_Checksum(uint16_t init, uint8_t* buff, int32_t len)
{
  uint32_t i = 0;
  uint32_t checksum = init;

  while(len >= 2)
  {
    checksum += ((buff[i] << 8) & 0xff00) | buff[i + 1];
    i += 2;
    len -= 2;
  }

  if(len)
  {
    checksum += (buff[i] << 8) & 0xff00;
  }
 
  while(checksum >> 16)
  {
    checksum = (checksum >> 16) + (checksum & 0xffff);
  }

  return (uint16_t)(~checksum);
}


How can i do this in B4A?

Regards,
Philip
 

MicroDrie

Well-Known Member
Licensed User
Basically, the difference between TCP and UDP is that UDP (User Datat Protocol) allow a faster connection speed without checking the data packets.
The original UDP checksum calculation is done over the complete packet including the packet header. The only difference is that the used way to calculate the checksum may missed a dropped bit. So the data connection layer detects “major” dropped bits and then retransmits packages with an invalid checksum. This does not alter the fact that on a higher layer another more accurate checksum can be calculated.

And speaking of reinventing the wheel :D, that's the beauty of new inventions. Under the hood there is often old proven technology that, through clever combinations and additions, leads to beautiful new solutions.
 
Upvote 0

annitb

Member
Licensed User
Longtime User
..."real-time" calculation of the checksum can be too much of a burden for the then limited resources...
This may sometimes be true if the checksum calculation is conducted char by char when the packet is constructed so ( even then the cost of revisiting the packet for calculating the checksum is saved ). To alleviate, one can use 8-bit or 16-bit or 32-bit buffers both for creating the packet and for calculating the checksum on the fly yielding speedups of sometimes 4x compared to per char construction ( and checksum calculation). Again extensive benchmarking ( and configurable parameter ) can yield whether 1-char or 8-bit or 16-bit or 32-bit buffers, ( plus remaining ) can be used to ensure that the packet is sent out quickly.

Again a different approach can be envisioned where it's not about constructing UDP packets only but about running a continuous UDPING to the 3 upstream servers ( this taking no memory at all ). Now usually this packet would contain just random meaningless data but when transmission is required the packet would contain meaningful data. This has the benefit of, let's say having 10 or 100 packets all malloced ( or r-malloced "random"-malloced, remember it's being sent continously with seemingly full data ) and ready for overwriting and sending ( using multithreaded async protocols ).

UDP sequence numbers ( or artificial ones ) can be 'rhash' instead of sequential, again allowing for the async nature to fill the sequence asynchronously. Now Asus Android tablets and phones seem to have the default route disabled ( one of the few worldwide ). This allows for all routes to be fairly dynamic and robust and this decision is left to the user device and thus doesn't have single point of failure issues with the 0.0.0.0 default route on most devices. This can help again as the 3 upstreams servers are being used. Now if there's a glitch in one, automatic route calculation can be done per thread ( again being helped by no default route ). This would be helped immensely if the UDP packets had some sort of performance data in them too, in addition to RHASH ordering ( not that one, this one: https://stackoverflow.com/questions/4273466/reversible-hash-function#13018842 ) . This need not be a systemtime metric because those are very expensive to continuously obtain but can be a processtime difference metric

eg - https://github.com/ArchiDroid/haveged/blob/master/src/havegecollect.c refer line 53:

clock_gettime(CLOCK_MONOTONIC, &ts);

could perhaps be

clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);

A much needed feature is "double buffering" across connections for bandwidth aggregation. This allows a blanket rule that the 3 upstream servers are being used for the same traffic and the packets return in duplicate or triplicate. Thus getting discarded upon reconstruction but ensuring that the one packet that is mostly the stuck packet holding up the entire buffer for succesful packet construction and checksum calculation has a much much greater chance of coming in from another server. Again the third server can perhaps specialise in sending the packets in reverse order so that the chance of errors in further lowered. All this is better of course because it's all async.

Stretch target, drawing your attention to this essay: https://www.codeproject.com/Articles/5436/Genetic-and-Ant-Colony-Optimization-Algorithms Note the text: "CMemDC is a class used for double buffering. This is a technique used in computer animation to avoid screen flicker, which was a major problem due to the fact that the screen is updated (repainted) several times each second. The technique used here is to create an off-screen buffer to which the image is drawn. The final image is then copied to the screen." Now while this 2R ( 2+reverse ) UDPING buffering protocol is great, for actual screen operation over intranet or even internet, why can this thinking not be extended to above network protocol, because a network protocol is in many ways similar to screen sharing ( ie some data has to be buffered and send out every so number of miliseconds ) but instead of sending the packets arbitrarily every 1ms ( or lesser ) is buffered and then sent out.

Also a point to note is that linux random device is now not blocking any more ( after some 20 years of so ) and it even perfoming at 200 MBPS! ( with or without haveged ) so such packet protocols needs not be intimidating from a developers perspective.
 
Last edited:
Upvote 0

MicroDrie

Well-Known Member
Licensed User
Now I also understand that I used to watch a grainy VHS recording and now have a very sharp video image. But yes the UDP protocol dates from the early days of data networks.

This post is about communicating with an existing device, where the communication must conform to the original protocol. Unfortunately, optimizing the resources is not appropriate, however nice that might be.
 
Upvote 0

annitb

Member
Licensed User
Longtime User
Refer:

https://www.geeksforgeeks.org/user-datagram-protocol-udp

If the packet modification strength is in C, then so be it. I'm not too across the B4A plugin libraries and how they're actually loaded. But they are most probably statically loaded into the exe.

There may be a case to have dynamically loaded dlls or .so objects to conduct certain activities and close down releasing all associated binary memory. This is different from what is known as .lib insertion into the EXE.

Dynamically loaded DLLs are very powerful because one is able to have hundreds of plugins in the app and they don't take memory.
 
Upvote 0
Top