Skip to content

Bug: makoCon hangs on unrecognized commands and malformed input #58

@SoumojitDalui

Description

@SoumojitDalui

Summary

makoCon's Redis-compatible server hangs (produces no response) when it receives an unrecognized command or a known command with wrong argument count. The client connection becomes stuck waiting indefinitely. Standard Redis behavior is to return -ERR unknown command or -ERR wrong number of arguments.

Reproduction

import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('127.0.0.1', 6380))

Send unknown command via RESP protocol

sock.sendall(b"*3\r\n$6\r\nFOOBAR\r\n$3\r\nkey\r\n$3\r\nval\r\n")

Server produces no response -- client hangs indefinitely

Send SET with no arguments

sock.sendall(b"*1\r\n$3\r\nSET\r\n")

Server produces no response -- client hangs indefinitely

Expected Behavior

Standard Redis returns:

  • FOOBAR key val-ERR unknown command 'FOOBAR'
  • SET (no args) → -ERR wrong number of arguments for 'set' command

Actual Behavior

makoCon produces no response at all. The TCP connection stays open but silent, leaving the client blocked on read. This can break connection pools and leave clients in an unrecoverable state.

Affected Commands

Input Expected Response Actual Response
FOOBAR key val -ERR unknown command No response (hang)
SET (no args) -ERR wrong number of arguments No response (hang)
GET k1 k2 (extra arg) -ERR wrong number of arguments Returns GET k1, ignores k2

Root Cause (Suspected)

The command handling lives in the Rust protocol layer (not makoCon.cc). The C++ side only receives pre-parsed TXN_OP_GET and TXN_OP_SET operations via FFI. The Rust RESP parser likely has a command dispatch path that handles the 7 known commands (PING, SET, GET, DEL, MULTI, EXEC, DISCARD) but lacks a default branch to send an error response for unrecognized commands or a validation step for argument counts.

Impact

  • Any Redis client library that sends unsupported commands (e.g., INFO on connect, CLIENT SETNAME, SELECT 0) will hang on the first unrecognized command
  • Connection pools become poisoned since the stuck connection is never released
  • Automated health checks that use commands beyond PING may hang

Suggested Fix

In the Rust command dispatch (likely in extern_interface/src/), add a default match arm that sends:

-ERR unsupported command '{command_name}'\r\n

Also add argument count validation for known commands before dispatching to the C++ layer.

Test Environment

  • Server: build/makoCon on port 6380
  • Mako Commit: 7431e71e (branch mako-dev)
  • Client: Python 3.10.12 with redis-py 7.1.0
  • Host: Linux 5.15.0-133-generic (x86_64)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions