diff --git a/src/main.c b/src/main.c index 99dfa1c..beccd82 100644 --- a/src/main.c +++ b/src/main.c @@ -18,10 +18,16 @@ const char *LOCALHOST = "127.0.0.1"; #define SERVERDATA_RESPONSE_VALUE 0 typedef struct { + // size of the remainder of the packet int32_t size; + // packet id (client sets, server echoes, -1 on auth failure) int32_t id; + // packet type (see the SERVERDATA_* constants) int32_t type; + // null-terminated command string (for auth and exec) or response string (from server) char body[4096]; + // yet another null byte after the body (required by protocol) + uint8_t _padding; } rcon_packet_t; int read_env_int(const char *var) { @@ -73,10 +79,9 @@ int rcon_connect(int port) { } void send_packet(int sockfd, int32_t id, int32_t type, const char *body) { - int body_len = strlen(body); - int32_t size = 10 + body_len; + size_t body_len = strlen(body); - size_t packet_size = sizeof(int32_t) + size; + size_t packet_size = sizeof(int32_t) * 3 + body_len + 2; unsigned char *packet = malloc(packet_size); if (!packet) { perror("malloc failed"); @@ -93,8 +98,8 @@ void send_packet(int sockfd, int32_t id, int32_t type, const char *body) { memcpy(packet + 8, &type_, sizeof(int32_t)); memcpy(packet + 12, body, body_len); - packet[12 + body_len] = 0; - packet[12 + body_len + 1] = 0; + packet[3 * sizeof(int32_t) + body_len] = 0; + packet[3 * sizeof(int32_t) + body_len + 1] = 0; ssize_t sent = send(sockfd, packet, packet_size, 0); if (sent < 0) { @@ -139,14 +144,20 @@ int recv_packet(int sockfd, rcon_packet_t *packet) { } packet->type = le32toh(packet->type); - int body_size = packet->size - 10; + int body_size = packet->size - sizeof(int32_t) * 2 - 2; if (body_size > 0 && body_size < (int)sizeof(packet->body)) { - bytes = recv(sockfd, packet->body, body_size + 2, MSG_WAITALL); + bytes = recv(sockfd, packet->body, body_size, MSG_WAITALL); if (bytes <= 0) { perror("recv body failed"); return -1; } packet->body[body_size] = '\0'; + + bytes = recv(sockfd, &packet->_padding, 1, MSG_WAITALL); + if (bytes <= 0) { + perror("recv padding failed"); + return -1; + } } else { packet->size = sizeof(int32_t) * 2 + 2; packet->body[0] = '\0';