-
Notifications
You must be signed in to change notification settings - Fork 18
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
Serverinfo string overflow #30
Comments
Actually it doesn't seem to be a constant limit, the maximum length appears to depend on the value of |
To me this looks as a serverinfo string overflow issue. The gametype on the server is set correctly but when the serverinfo string is transmitted to the client it gets messed up (overflowing the max length eventually) so on clients the gametype is parsed erroneously and the UI reacts accordingly (just print the serverinfo string on the client to debug it, +set developer 1 would do it if I recall correctly). |
Thanks @danielepantaleone I'll give that a go another day (I wasted all my time today trying to find a server name that didn't break it :D) [edit] It also depends on which map is loaded! |
Yes, be aware that the "version" cvar in the infostring on Mickael9 builds can be longer than in the official builds, as they include git rev etc (search for all "VERSION" appearances in Makefile). |
Hi Thomas, thank you for opening this issue and troubleshooting, because now we are closer to it being fixed eventually. I had my fair share of problems with wrong gametype being set, spent some time testing etc... Being lazy sys admin, I've always reused my configs (not just for games), but eventually it came to my mind that if others are not experiencing and reporting same issues the error is probably on my side. I never did proper advanced troubleshooting, but just by paying attention to logs, the only error that was consistently popping up was server info too long, so I shortened the name of server. Another server that had similar issue occasionally was the map rotating server, usually named |
The map name is part of the serverinfo string, so if it's long it can overflow. I agree that adding extra info to the infostring (such as git revision, build number, etc) is not helping |
Thanks Karnute, this seems like a good candidate, git revs can be pretty long at up to 40 chars depending on the truncation.
Hey spiki! I was doing the same thing, it was driving me nuts, just kept making it shorter and shorter until finding that even mapnames were affecting it as you have discovered as well. But as Daniel pointed out above the mapname is of course also part of the severinfo string so it all matches Daniel's suggestion so far. I did notice some kind of max string length warning being occasionally printed out to the shell the server was running in but this even seemed to be the case with default config so I thought maybe it was a more generic and benign issue. I suppose not every truncation of the serverinfo string will necessarily cause incorrect parsing which explains why these warnings do not always coincide with this particular manifestation of the issue, just whichever combination finally pushes the value of g_gametype off the cliff :P, I wonder what else reaches that fate first. I'll try have a dig into this tonight. |
Yeah unfortunately we can't really fix this issue as it would break the compatibility with Quake 3 and its 1024 chars limit for the serverinfo string. We've been trying to limit the number and length of cvars that we add to the serverinfo string since 4.2.001 but it clearly isn't enough to get rid of the overflow issues. |
Ok I did wonder this as the obvious solution is to change the limit, but that obviously requires a difference in the client. Well for this repo at least the git rev can be truncated to something less demanding, git describe can be used to produce the minimum unambigous truncation. More generally it might be good have a functional failure modes. i.e ensure a correctly parsable serverinfo string with at least all of the functionally important cvars by truncating any superficial variable length values when necessary. Some obvious candidates in order of least importance would be: I suppose mapname is the most annoying because it could potentially affect the truncation of other superficial values on each map cycle making it unpreditable for server admins. Without really knowing how this thing works yet, here's another thought: is it possible to have a backwards compatible overflow? i.e does the truncation of the serverinfo string happen at the client end? in which case my former solution can be used to force the length to a 1024 parsable chunk, then use a variable length overflow to store the truncated parts for custom clients that are able to use it to rebuild a the larger original serverinfo string (i.e the UrT engine could have longer serverinfo values while quake3 compatible ones would get some truncated values but operate correctly otherwise). </mass speculation> |
I was thinking the same thing. At minimum would it be possible to re-order the items in the string so that the most important information is first in the string and will get parsed, and if there is an overflow, the last information given (g_motd etc) would get truncated from the string? |
That would certainly be a good start to mitigate the issue. I think all of these solutions build up quite nicely on top of each other as a route to a potential complete fix:
The first 2 get most of the way with minimal work, 3 and 4 might be a little over the top but we can try if they turn out to be necessary. |
Ok, after spending a couple hours looking into this, this appears to be where the server sets the serverinfo string: The client appears to parse that string here: Digging deeper, it looks like this is the function that the server uses to decide what goes into the serverinfo string: And this is the function that actually builds that string: Let me take a sec to just talk through the code that builds the serverinfo string. It looks like it initializes a character array to the max allowable length, and then it loops through all the cvars. When it reaches a cvar that it should add to the string, it runs the string builder function sending it the character array, the cvar name and the cvar value string. Then the string builder adds the the cvar name and value to the serverinfo character array. Now if the serverinfo string would be too long if the string builder function added the new cvar value, then it simply returns without adding it. That's it. There is no built in method for knowing what was missed or what cvars are more important, etc. Not to mention, the function that is picking the cvars to add to the serverinfo string, has no way of knowing if the cvar it wants to add is too big or if the serverinfo string is close enough to being full that another cvar cant be added to it. I'm not sure what the best way to solve the problem would be, but clearly some better error reporting and logic built into it to make sure that the most important cvars are in the serverinfo string and maybe just truncate the least important like the motd. Unfortunately it doesnt look like it would be easy to add an overflow string like @ThomasBrierley was thinking, but I may be wrong on that. |
Thanks for digging those up Kronik 👍
It looks that way, but the concept of essentially "sending the extra bits for custom clients" could be achieved separately also. But that was just an extra nice to have, most important is to make it functionally reliable, and from what you've found that looks possible. |
Mitigate the serverinfo overflow issue by reducing the version cvar length which is somewhat longer than the official engine by 33 chars. - Abbreviate PRODUCT_NAME to match official (will affect pid filenames) - Remove redundant product name from makeFile VERSION - Reduce git info to rev alone (commit date can be inferred from hash) Mitigates mickael9#30
Shortening the version alone was a quick win, it's fixed it for my current server.cfg but it will no doubt need more work for more hungry server and map name combos. |
This definitely should work for the majority of servers, but it would be nice to find a way for it to fail gracefully and provide useful feedback to a server administrator without needing to grep logs to find out their sever name is too long when certain maps are loaded. |
Yeah maybe, it only actually removes 27 chars, I was expecting more but I guess that's how close it is flying to the limit so it helps.
This might be possible if checking against the max length map name available upfront (I think mapname is the only variable length one while running). |
I found even with the shortened version cvar the infostring can become longer, specifically when tweaking things with rcon. I ended up striping the PLATFORM_NAME/DATE as well just to stop it from breaking. I had a look at the content of infostring I'm not sure the previous suggestions are going to be very applicable... first of all there aren't many non-functional cvars, (motd and welcome message are not included). So it's not immediately obvious what is not useful. However I noticed that things like bomb mode cvars are sent regardless of game type, so one possible solution would be to find out which cvars are contextual and exclude them from irelevant combinations (and then hope that the worst case combination actually reduces in length). |
TL;DR default server.cfg verbosity is mostly to blame I've compared my test server infostring to other public servers to find some significant differences beyond just cvar values. There are a few subtle differences caused by the engine, specifically Many servers just ommit default cvars from their config resulting in a vastly shorter infostring. These can be easily compared using the website: http://www.urbanterror.info/servers/list/ The "settings:" section for each page enumerates the serverinfo string. This one has particularly minimal serverinfo: Mine is comparably very long: Mine is new and just uses the default server.cfg with a few tweaked values. It's pretty obvious from this that ommitting cvars with default values from infostring is going to be a big win and far simpler than previous ideas. Although this does not gaurantee no overflow, it should work in almost all cases since a server.cfg would need close to every cvar value to be non-default for the issue to occur. |
@ThomasBrierley, As far as I know, even if the cvar is not in the server.cfg it sends the default value as a part of the serverinfo string. But I haven't looked closely enough at the code to verify this statement. |
Following the spirit of suggestions here, about reordering of cvars in infostrings, I have created a patch https://github.com/karnute/ioq3/tree/cvar_infoseclong with a new flag to mark secondary cvars that are inserted into infostrings in a second batch karnute@8452121 . So important cvars are inserted first and then the probability of them being left out by exceeding the length is reduced. |
So far as I can see this looks like an excellent solution. I think I'd like to test it maybe with a super long map name and some long server names etc to see how well it works. This should only affect the server build right? |
Yes, I tested with extra long hostnames and it left out only some cvars (not g_gametype), and also the warning messages say which ones are left out. |
I've been basing this on the "InitGame:" message in the server console (uses With an empty server.cfg there are 52 cvars (the difference from my earlier observation is due to the website listing some cvars in different places). This is the same for both the official engine and this one, except for two cvars which are different they are the same list. When comparing this to the default server.cfg these are the extra ones that will only be included in the infostring iff user defined (These are only what I discovered in the default cfg, there may be other optional cvars also.):
Mostly all of the auth cvars, admittedly not as many as I thought, but enough to make a substantial difference 128 chars + a variable length depending on team names and dlURL (doesn't sound like much but that's > 12% of the available chars). It does make me wonder though if it's possible to omit some of the others and what the existing clients behavior is when they are omitted. [edit] Nice work @karnute, In light of that I think i'll abandon my above idea 😃 |
Mitigate the serverinfo overflow issue by reducing the version cvar length which is somewhat longer than the official engine by 33 chars. - Abbreviate PRODUCT_NAME to match official (will affect pid filenames) - Remove redundant product name from makeFile VERSION - Reduce git info to rev alone (commit date can be inferred from hash) Mitigates mickael9#30
* Fix serverinfo overflow - reduce version cvar Author: @ThomasBrierley Mitigate the serverinfo overflow issue by reducing the version cvar length which is somewhat longer than the official engine by 33 chars. - Abbreviate PRODUCT_NAME to match official (will affect pid filenames) - Remove redundant product name from makeFile VERSION - Reduce git info to rev alone (commit date can be inferred from hash) Mitigates #30 * Fixed typo Author: @BidyBiddle The **q** in ioq3 is always lowercase!
I have created an alternative patch https://github.com/karnute/ioq3/tree/cvar_infoprimary with the reverse meaning of the new flag (CVAR_INFOPRIMARY) to mark the relevant or important cvars that should go first when building the infostrings (instead of marking the secondary ones as in the other patch). I thought it should be equivalent but more clear and maintainable in the future, because if any important cvar is kept out by future overflows, then it could be marked as primary in the code. |
I don't know why this issue got closed in the first place after the merge of the request (I specifically merged without closing related issues, so I guess Github messed up something). Anyway sorry about that. I'm not sure about the changes to CVAR flags....the problem here is not the engine but it's Urban Terror that needs to stay compatible with vanilla Q3A, hence the serverinfo string limit cannot be increased. I agree that here we are trying to address (or better, trying to bypass) an issue related to Urban Terror limitation, but I don't know if this is the right path (I have no other ideas though). |
The new cvar flag does not affect compatibility with vanilla Q3A, because the same infostring overflows would occur also with vanilla Q3A and important cvars left out of it would cause the same errors. |
Obviously it won’t affect compatibility with vanilla Q3A since it’s not vanilla Q3A but a custom fork. If you read again my reply I’m pointing out only that we are trying to circumvent an issue using these additional flags, while there could be a much easier way if only Urban Terror would not have to stay compatible with vanilla Q3A. |
My fault sorry, GitHub autocloses issues when merging a PR with a "fixed" keyword preceeding a reference to the issue in body or a commit message. |
@danielepantaleone The point that @karnute was trying to make was that a server built using his custom flags wont affect a vanilla Q3A client in any way. A vanilla Q3A client will not have any issue since the info strings are put together server side. Merging Karnute's code only affects the server build and not the client build, so there should be no conflicts with vanilla Q3A client. EDIT: So much miscommunication in this thread. After re-reading @danielepantaleone comment again, I realize that he wasn't objecting just pointing out that he wishes that we could just up the limit. |
@karnute are you going to make a PR for your solution? |
Yes, but first I must check why the second alternative https://github.com/karnute/ioq3/tree/cvar_infoprimary (which I prefer) results in different ordering of cvars from the first one https://github.com/karnute/ioq3/tree/cvar_infoseclong , and currently I am very busy. Probably in a few days... |
Any news @karnute ? |
This is a strange one, had me scratching my head for a while.
If
sv_hostname
is longer than 25 chars (including hidden colour code chars) the game type is forced to FFA. Note that the server will still advertise whateverg_gametype
was set to andrcon g_gametype
will still return whatever it was set to while running, yet the actual game mode used will be FFA.This behaviour doesn't seem to occur with Barbatos's repo.
[edit]
Thanks for everyones invaluable input on this. Rough plan from discussion bellow:
Ommit cvars with default values (Default server.cfg causes all defaults to be sent unecessarily).Determine superficial cvars and truncate their values when limit exceeded in order of importance.Add 2nd serverinfo string containing untruncated cvars (without interfering with strict q3 protocol).Exclude truncation based option since reviewing content of infostring (almost all cvars are not strings).
Exluded omitting cvars option because the optional ones are mostly auth cvars.
Kronik has detailed relevant functions here #30 (comment)
The text was updated successfully, but these errors were encountered: