-
-
Notifications
You must be signed in to change notification settings - Fork 84
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
uptime mod - fix structhack and sanitize struct data types. #548
base: develop
Are you sure you want to change the base?
Conversation
want to test this with the server |
@thommey: can i do anything to help with the test? |
Can you run it on a bot for a few days? We'll tell you if the server explodes :) |
the memory allocation for flexible array members are apparently subject to some uncertainty regarding offsetof() vs. sizeof(). sizeof can include padding bytes after the last non-vla member, while offsetof does not. so, an actual non-vla member can require a smaller size than sizeof(struct x)+strlen(vla) calculates. I mostly switched to omitting the member and just sending the packed struct as header and then the rest. with attribute((packed)), which we should be using anyway, this problem might go away on its own. it wouldn't actually be a problem to send a packet too long, the last element is a string and \0 terminated. so we can most likely just leave it like you have it now see https://stackoverflow.com/questions/44745677/flexible-array-members-can-lead-to-undefined-behavior and similar for discussion |
Uncertainty regarding offsetof vs. sizeof can be treated by using them correctly, so whatever stackoverflow sais: offsetof <= sizeof regarding any struct is obviously true, because offsetof is only equal to sizeof, if the last element is of ZERO size, and there is uncertainty about the size of an vla. I enhanced our code to use offsetof instead of sizeof. By "I mostly switched" you mean, you unstruckhacked a structure into two parts? One can always do that. Its a question of style preference. Yes, packing should be used for network packets. But only for network packets. It hurts performance. There are other use cases, embedded systems, memory limits, but that would be off topic now. I was already looking at padding/packing before, because whenever a struct is shared, via network or file or whatever, we have a portability issue. The code worked, so from that alone one can tell that there can't be much padding/packing. It would break the network. Ok, its not absolutely true. It broke for 32 vs. 64 bit because of uncertainty about integer size and some padding bytes at the very end of the struct. That's what the old workarounds were about. Now my patch fixes this. It removes any uncertainty about member sizes of the struct, and also about padding/packing, because all members are same certain size each. Normally you would have a hard requirement for pack here, as you wrote, but in this case, we are clear without it now. |
Testbot is running since 3 days, see: The tcpdump of the first packets is shown above, so i don't expect any surprize. If you don't need this testbot any longer, let me know pls, i could use system resources elsewhere, ty! Should we bump this version number? |
if we clean this up, I'd like a packed structure and using the unused "regnr" to identify "new version" packets, maybe simply make it a version field. it should be 0 for all eggdrops, not sure about energymechs, would need to be evaluated (easiest in the actual server probably) |
also needs a server update then, but at least we have defined sizes then |
Note to my future self: Maybe we should not do the nmalloc / memcpy(mem, upPack) nor use flexible array member here, but simply set PackUp char string to the maximum size possible, which is not much, probably below 512 bytes. Its a good tradeoff for the simplification in sourcecode that we get out of this plus the nmalloc/memcopy was not for free also. |
Merge done to trigger new CI run
Merge done to fix merge conflict
Merge done to fix merge conflict
Found by: wakco
Patch by: michaelortmann
Fixes: #377 and #664
One-line summary:
Fix structhack with sane code, sanitize struct data types and replace rand() with random()
Additional description (if needed):
This patch requires merged #660!
Side effect of new code is better network usage, due to proper ending of the send network packet with one \0 instead of useless additional \0s.
Datatypes within struct are result of
uint32_t htonl(uint32_t hostlong);
(see man htonl) and the server understands 32 and 64 bit.
So the struct was sanitized and uses fixed datatype uint32_t now.
While at it, i replaced rand() with random(), so eggdrop will only uses one random function everywhere.
Some comments were cleaned up regarding line length.
tab -> space
gethostbyname() -> getaddrinfo() to prepare for ipv6 ;) and modernize network code
static functions
tcpdump test below...
Test cases demonstrating functionality (if applicable):
eggdrop.conf:
i modified the code to test this:
uptime.c:
before:
static int update_interval = 720;
after:
static int update_interval = 1;
uptime.c:
before:
hexdump -C before.dat
hexdump -C after.dat
20181014 tcpdump of the first sent packets: