..."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.