Jump to content

rcon returning invalid responses


rfalias

Recommended Posts

On occasion, using rcon cli or rcon libraries for python, and even python-valve the rcon server returns empty byte responses and causes exceptions with these libraries.

It's hard to pin down when it happens, rcon-cli has been the most stable but still on occasion gets a dead response from the PZ server. It will return nothing, then you can run it again and it will complete. Not sure if its a resource or timing issue.

 

Steam Latest, dedicated server on ubuntu

Version: 41.61

Using steamcmd

 

Edited by rfalias
Link to comment
Share on other sites

  • rfalias changed the title to rcon returning invalid responses

I confirm there's definitely a bug in PZ RCON implementation. For example when I send the SERVERDATA_AUTH packet to pz server, when everything goes fine the response is 14 bytes long, but sometimes it's 28 bytes long.

 

For example, when I send this exact same payload multiple times:

12000000414243440300000031323334353637380000

 

sometimes the response is valid (14 bytes):

0a00000041424344000000000000

 

but sometimes not (28 bytes):

0a000000414243440000000000000a00000041424344020000000000

 

When it fails you can clearly see the response contains twice the expected response payload.

 

Here's a python code sample I've been using to troubleshoot this issue:

#!/usr/bin/python3

import os
import socket
import struct

def serverdata_auth(socket, rcon_id, passwd):
	passwd = bytes(passwd, encoding='ascii')
	rcon_type = struct.pack('I', 3)
	packet_size = struct.pack('I', 10 + len(passwd))
	payload = packet_size + rcon_id + rcon_type + bytes(passwd) + b'\x00\x00'
	print(payload.hex())
	return socket.send(payload)

def serverdata_auth_response(socket, rcon_id):
	response = socket.recv(4096)
	print(len(response))
	print(response.hex())
	if len(response) != 14:
		raise Exception('Invalid response length')

	size, sess_id, rcon_type, b1, b2 = struct.unpack('IIIcc', response)

def rcon_command(host, port, passwd, command):

	sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	sock.connect((host, int(port)))

	rcon_id = b'\x41\x42\x43\x44' #os.urandom(4)
	print('RCONID: %s' % rcon_id.hex())
	serverdata_auth(sock, rcon_id, passwd)
	serverdata_auth_response(sock, rcon_id)

rcon_command('127.0.0.1', 27015, '12345678', 'players')

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...