Drain auth socket reads to avoid dropping partial packets on close

This commit is contained in:
Kelsi 2026-02-13 01:12:59 -08:00
parent 280c6ffa1d
commit 9091cb0496

View file

@ -124,28 +124,45 @@ void TCPSocket::send(const Packet& packet) {
void TCPSocket::update() { void TCPSocket::update() {
if (!connected) return; if (!connected) return;
// Receive data into buffer // Drain the socket. Some servers send small packets and close immediately; a single recv()
uint8_t buffer[4096]; // can return a partial packet, and the next recv() may return 0 (FIN) which would otherwise
ssize_t received = net::portableRecv(sockfd, buffer, sizeof(buffer)); // make us drop the buffered bytes without parsing.
bool sawClose = false;
bool receivedAny = false;
for (;;) {
uint8_t buffer[4096];
ssize_t received = net::portableRecv(sockfd, buffer, sizeof(buffer));
if (received > 0) { if (received > 0) {
LOG_DEBUG("Received ", received, " bytes from server"); receivedAny = true;
receiveBuffer.insert(receiveBuffer.end(), buffer, buffer + received); LOG_DEBUG("Received ", received, " bytes from server");
receiveBuffer.insert(receiveBuffer.end(), buffer, buffer + received);
continue; // keep draining
}
// Try to parse complete packets from buffer if (received == 0) {
sawClose = true;
break;
}
int err = net::lastError();
if (net::isWouldBlock(err)) {
break;
}
LOG_ERROR("Receive failed: ", net::errorString(err));
disconnect();
return;
}
if (receivedAny) {
tryParsePackets(); tryParsePackets();
} }
else if (received == 0) {
if (sawClose) {
LOG_INFO("Connection closed by server"); LOG_INFO("Connection closed by server");
disconnect(); disconnect();
} }
else {
int err = net::lastError();
if (!net::isWouldBlock(err)) {
LOG_ERROR("Receive failed: ", net::errorString(err));
disconnect();
}
}
} }
void TCPSocket::tryParsePackets() { void TCPSocket::tryParsePackets() {