phpsocketsclamav

Can I send multiple commands to clamd socket (ClamAV daemon) without closing and re-opening the connection?


    $socket = socket_create(AF_UNIX, SOCK_STREAM, 0);
    socket_connect($socket, CLAMD_SOCKET);

    socket_send($socket, 'PING', 4, 0);
    socket_recv($socket, $output, 4, 0);

    // check to see if $output === PONG (which it is)

    $scan = 'SCAN ' . $file;
    socket_send($socket, $scan, strlen($scan), 0);
    socket_recv($socket, $output, 100, 0);

    // $output should contain the result from the socket, but instead it's blank
    // var_dump says it's a 1 character string " "

This is my original code.

However, if I close the socket after the PING command and PONG is returned (which it is), then re-open it again, the SCAN command works and it returns the result as expected.

Is this how it's supposed to work, or do I need to do something else in between the commands? Is the socket not ready for another command to be sent?

I'm not really sure what to look for, I can't find anything in the PHP manual. It does work, but I feel as if having to close the socket and re-open it is the wrong way to do things.


Solution

  • I can't find anything in the PHP manual.

    The behavior does not depend on PHP but on the protocol spoken between the client and the server - i.e. what protocol is expected and enforced by clamd. Therefore no information about this could be found in the PHP documentation, but one would need to look into the ClamAV documentation instead.

    While the clamd documentation describes the commands it unfortunately lacks the information if multiple commands are allowed. A short test (for example with netcat) shows though, that clamd closes the connection after the response to the command, so no more commands on the same connection are possible.

    It does work, but I feel as if having to close the socket and re-open it is the wrong way to do things.

    It is definitely not the most efficient way of doing things, but the overhead on UNIX domain sockets or even local TCP sockets for creating a new connection is low - compared to establishing a TCP connection to a remote system.

    Being able to send multiple commands and therefore get multiple responses would require a clear separation on where a command and response ends though. This is kind of documented for commands, but not for responses. So the only obvious option here is to read until the end of the connection, i.e. until connection close. This design makes it impossible though to send more commands on an established connection.