EPOLLHUP does not mean that all data has been read from the connection. From the epoll_ctl(2) man page:
Note that when reading from a channel such as a pipe or a stream socket, this event merely indicates that the peer closed its end of the channel. Subsequent reads from the channel will return 0 (end of file) only after all outstanding data in the channel has been consumed.
This means that the server may currently ignore arbitrary messages sent by the client immediately before the client closes the connection.
I noticed this race occur in practice with an ext-session-lock-v1 client that exits immediately after making the unlock_and_destroy request. Using strace I determined that the client does indeed make this request using sendmsg() before exiting. However logging on the server side indicated that the request was never received. The server instead saw only the termination of the client.
This race affects all clients and protocols but is particularly noticeable and problematic in this case.
The fix is simple: Ignore EPOLLHUP and continue to read until 0 is returned, indicating that all data the client sent has been read.
Signed-off-by: Isaac Freund email@example.com