Talk:Source RCON Protocol

From Valve Developer Community
Jump to: navigation, search

This article was taken from a HLDS_APPS posting by Alfred Reynolds.

Additional Remarks have been added to Alfred's Documentation. This is taken from the KQuery Wiki (http://wikki.kquery.net/), as unfortunately the page is defaced. One can dig deeply through the revision history to obtain the information, some of which is vital to creating a working implementation.. I have taken the liberty of echoing it here. 20:51, 4 Feb 2006 - Erik Hollensbe

The C app (CLI / rcon.c) unfortunately does not work for me. I either get 'authentication failed' or 'Illegal size -559038737'. Maybe the app does not like 64bit Linux. Other apps (like SRCDS.py) work just fine but their code is hard to understand, and they require Python and the like. I googled for a better C implementation but couldn't come up with anything. Too bad there isn't a more official tool for this, as it can be really useful for maintaining servers remotely. Andreas Klauer 06:13, 14 Jul 2008 (PDT)

Packets splitting confusion

I have Ruby code able to receive really long RCON responses from Source servers. This works (even for cvarlist = 43 packets) almost flawlessly. But cvarlist (and maybe other requests) fails in around 1 of 4 tries. The problem is that the packet size of the split packets is wrong. It doesn't show the complete size of the packet, but only until the first zero-byte (0x00, the end of the first string component). In my experience the second string component isn't used very often, so the response is a string terminated by 2 zero-bytes in almost all cases. It's quite interesting that this error happens when the text of the response is split into the two strings. Even more interesting is that this happens always in the same section of the text (for cvarlist just in the middle of the description for ai_show_connect). In the moment I'm pretty sure this is a bug in Source as I can't imagine a purpose of this random behavior. --Koraktor 10:20, 8 Dec 2008 (PST)

I'd post that on hlcoders. --TomEdwards 10:47, 8 Dec 2008 (PST)
Already had that in mind. Thanks for the reminder. ;) --Koraktor 11:06, 8 Dec 2008 (PST)

How to receive split response?

How to receive a split response correctly? There's nothing that indicates that the packet is split, so currently I just continue listening for additional packets with the correct id and concatenate the string1 together until a timeout occurs. This works fine for cvarlist. I'm planning on optimizing this, by listening for additional packets only if the previous packet was long, i.e. if the probability for additional packets is high - this should work assuming that a split always means that the previous packets use the maximum length for string1 (4096 or something bytes according to the spec here). However this still means there is some chance I have to continue listening (and thus blocking the result) for nothing. Anyone know of a better way? Frostschutz 11:29, 26 January 2010 (UTC)

Ok, it seems a heuristic is necessary here. For a cvarlist I get 37 packets, and ignoring the last packet (3436 bytes), the split packets were between 3915 and 4103 bytes in size. The size is not constant because the output seems to be split by lines, instead of bytes... each packet starts with a cvar and ends with a \n. So I looked at the length of lines and they were between 0 and 201 characters. So for safety I will assume a maximum line length of about 400 characters (about two times the maximum of cvarlist) so if a packet is 3700 bytes or larger it will assume that another packet may follow. So my implementation will block and listen (until timeout) in this case, and otherwise just poll. This avoids unnecessary blocks for short responses or split responses that have a short last packet. If anyone has any better suggestions, please share. Frostschutz 17:24, 26 January 2010 (UTC)

I found an alternative method that does not rely on heuristics, but it might be seen as a hack: Empty requests sent to the server, return an empty response. This means that if you send a (series of) request(s) to the server, you can follow it up with an empty request. This will act as a terminator: you know that you received the reply completely as soon as you receive the response to your terminator request. The downside of this is that it will add an additional entry to your server log (rcon from "1.2.3.4:5678": command "") and will add an overhead of 2 packets to every (series of) request(s).

Even if you decide to not use terminator packets, your implementation should be aware of changing request ids when sending a series of requests, so only the last request will have to wait for additional packets that will never come if the above heuristic fails. Frostschutz 13:04, 8 February 2010 (UTC)

...and here's the hack made perfect: instead of sending an empty command, just send another SERVERDATA_AUTH request on an already authed connection as a terminator. The server will reply properly without adding an entry to the logs. Combine that with the previously used heuristic, i.e. send the terminator request only if a) you received a packet that's large enough to assume it may be split, b) there are no other requests to be sent in the queue. This way the heuristic will never wait for a packet that will never come because you definitely get a packet (your terminator packet). Worst case you have to wait $ping ms for the server to send your terminator packet back. Frostschutz 16:01, 8 February 2010 (UTC)

- There's even a better solution for sending a SERVERDATA_AUTH request. Just send an empty SERVERDATA_RESPONSE_VALUE packet. The server will reply with an empty SERVERDATA_RESPONSE_VALUE packet, too. That way you don't have to save the password for an additional SERVERDATA_AUTH request to avoid the risk of being banned for using the wrong password. --Koraktor 14:29, 20 February 2011 (UTC)

- It seems like Left4Dead 2 (maybe 1 also) will sometimes "hiccup" when sending SERVERDATA_RESPONSE_VALUE packets for termination. It will send a packet like the following:

0e 00 00 00 4c bb 00 00  00 00 00 00 00 01 00 00 ....L... ........
00 00                                            ..

I don't know exactly what this is, but the packet length of 14 (0x0E) and the data is specific for that kind of packet. It seems like those packets can be safely discarded. --Koraktor 19:04, 9 March 2011 (UTC)

This discussion is somewhat old, but I discovered another possibility to deal with split responses. At the end of each response, the server mirrors the original command. E.g.

L 05/22/2020 - 13:42:38: rcon from "127.0.0.1:60892": command "maps *"

So I just keep reading packets, until I find this string. EDIT: This needs "logecho 1" to be set in config.

CS2 Multipacket

I'm just trying to use rcon on a CS2 server. It seems, that multipacket responses are handled differently / bigged there. If I log the packet size and id of the decoded packets, I get the following for a cvarlist: packet id = 86 size = 331570 packet id = 538976288 size = 538976288 packet id = 975183904 size = 538976288 packet id = 1919248748 size = 1885959276 packet id = 538976288 size = 538976288 packet id = 538976288 size = 538976288 The first ID is correct, but thereafter it's bullshit. So maybe the packet is encoded differently? Has anyone tried the new server? --Taraman (talk) 23:56, 17 October 2023 (PDT)

Further research makes me think, that there are no multipacket answers anymore. The size/id of 538976288, which appears very often here translates to Hex "0x20202020", which means 4 spaces (%20%20%20%20). So my library seems to split a single large packet into smaller ones and tries to interpret the lots of spaces, which are present in the cvarlist, as packet headers. --Taraman (talk) 08:36, 18 October 2023 (PDT)

Moved to Talk from article

I've just done some significant rewriting of this article, including removing some discussions, which for some reason happened on the article page itself. I've gone ahead and copied them here for posterity. Speedhaxx 15:40, 31 October 2012 (PDT)

  • If the response spans over multiple packets only the first has these fields. The Other packets are just data.
  • It seems to me, that this has been changed, my response are including those fields. --Plastofix 18:46, 19 Dec 2007 (PST)
  • I agree with you. But i have no idea how can i understand that it is multiple packets. Can anybody tell me how to recognize it ?

---

  • CS:Source server sends one junk packet during the authentication step, before it responds with the correct authentication response.
  • It seems this junk packet is also valid under HL2:DM, not just CS:Source, so probably applies to all Source games (unless Rcon stuff is done differently in other Source powered games by 3rd parties). --Bartk 12:13, 2 Oct 2006 (PDT)
  • It's not a junk packet, it contains "Banning 192.168.1.42 for rcon hacking attempts" (if you happen to get banned from your server while authenticating). Dangan 05:27, 5 Feb 2008 (PST)
  • It sends junk packet. If you receive SERVERDATA_RESPONSE_VALUE first, you need to Read data from socket one more time to get correct auth packet.
  • The packet size field does NOT include the size of the packet size field itself. That is why the minimum length is 10 -- four bytes for the two integers (request ID and command) plus two bytes for the potentially empty ASCIIZ strings.
  • Make sure that you code the ability to handle multiple response "packets". With a 32-player server, it will use these commonly for status commands (for instance), just as HLDS often did. Also, keep in mind that you won't be able to read the whole "packet" at one time -- you need to keep reading in a loop until you receive the entire packet before processing it.

Cannot Connect to Team Fortress 2 Dedicated Server

I run a Team Fortress 2 Dedicated Server. So what is going on is that in order to enable RCON in a Team Fortress 2 Dedicated Server, you must add a +ip xxx.xxx.x.xxx -port 27015 string to the startup sequence. But when I add this string to my START.bat file, when I or anyone else tries to join, it fails after four tries. Any suggestions on how to fix this problem?