Merge branch 'tcp-reset-connection-on-failed-send-9.18' into 'v9.18.28-release'
[9.18][CVE-2024-0760 (part 3)] Reset the TCP connection on a failed send See merge request isc-private/bind9!722
This commit is contained in:
+32
-4
@@ -2369,14 +2369,41 @@ isc__nm_process_sock_buffer(isc_nmsocket_t *sock) {
|
||||
int_fast32_t ah = atomic_load(&sock->ah);
|
||||
isc_result_t result = processbuffer(sock);
|
||||
switch (result) {
|
||||
case ISC_R_NOMORE:
|
||||
case ISC_R_NOMORE: {
|
||||
/*
|
||||
* Don't reset the timer until we have a
|
||||
* full DNS message.
|
||||
*/
|
||||
result = isc__nm_start_reading(sock);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
|
||||
/*
|
||||
* Restart reading if we have less data in the send
|
||||
* queue than the send buffer size, this means that the
|
||||
* TCP client has started reading some data again.
|
||||
* Starting reading when we go under the limit instead
|
||||
* of waiting for all data has been flushed allows
|
||||
* faster recovery (in case there was a congestion and
|
||||
* now there isn't).
|
||||
*/
|
||||
size_t write_queue_size =
|
||||
uv_stream_get_write_queue_size(
|
||||
&sock->uv_handle.stream);
|
||||
if (write_queue_size < ISC_NETMGR_TCP_SENDBUF_SIZE) {
|
||||
if (sock->reading_throttled) {
|
||||
isc_log_write(isc_lctx,
|
||||
ISC_LOGCATEGORY_GENERAL,
|
||||
ISC_LOGMODULE_NETMGR,
|
||||
ISC_LOG_DEBUG(3),
|
||||
"resuming TCP "
|
||||
"connection, the other "
|
||||
"side is reading the "
|
||||
"data again (%zu)",
|
||||
write_queue_size);
|
||||
sock->reading_throttled = false;
|
||||
}
|
||||
result = isc__nm_start_reading(sock);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Start the timer only if there are no externally used
|
||||
@@ -2388,6 +2415,7 @@ isc__nm_process_sock_buffer(isc_nmsocket_t *sock) {
|
||||
isc__nmsocket_timer_start(sock);
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
case ISC_R_CANCELED:
|
||||
isc__nmsocket_timer_stop(sock);
|
||||
isc__nm_stop_reading(sock);
|
||||
|
||||
+11
-19
@@ -1162,25 +1162,10 @@ tcpdns_maybe_restart_reading(isc_nmsocket_t *sock) {
|
||||
if (!sock->client && sock->reading_throttled &&
|
||||
!uv_is_active(&sock->uv_handle.handle))
|
||||
{
|
||||
/*
|
||||
* Restart reading if we have less data in the send queue than
|
||||
* the send buffer size, this means that the TCP client has
|
||||
* started reading some data again. Starting reading when we go
|
||||
* under the limit instead of waiting for all data has been
|
||||
* flushed allows faster recovery (in case there was a
|
||||
* congestion and now there isn't).
|
||||
*/
|
||||
size_t write_queue_size =
|
||||
uv_stream_get_write_queue_size(&sock->uv_handle.stream);
|
||||
if (write_queue_size < ISC_NETMGR_TCP_SENDBUF_SIZE) {
|
||||
isc_log_write(
|
||||
isc_lctx, ISC_LOGCATEGORY_GENERAL,
|
||||
ISC_LOGMODULE_NETMGR, ISC_LOG_DEBUG(3),
|
||||
"resuming TCP connection, the other side "
|
||||
"is reading the data again (%zu)",
|
||||
write_queue_size);
|
||||
sock->reading_throttled = false;
|
||||
isc__nm_start_reading(sock);
|
||||
isc_result_t result = isc__nm_process_sock_buffer(sock);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
atomic_store(&sock->reading, true);
|
||||
isc__nm_failed_read_cb(sock, result, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1284,6 +1269,13 @@ isc__nm_async_tcpdnssend(isc__networker_t *worker, isc__netievent_t *ev0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_NETMGR,
|
||||
ISC_LOG_DEBUG(3),
|
||||
"throttling TCP connection, the other side is not "
|
||||
"reading the data, switching to uv_write()");
|
||||
sock->reading_throttled = true;
|
||||
isc__nm_stop_reading(sock);
|
||||
|
||||
r = uv_write(&uvreq->uv_req.write, &sock->uv_handle.stream, bufs, nbufs,
|
||||
tcpdns_send_cb);
|
||||
if (r < 0) {
|
||||
|
||||
+12
-19
@@ -1377,6 +1377,14 @@ tls_cycle_output(isc_nmsocket_t *sock) {
|
||||
break;
|
||||
}
|
||||
|
||||
isc_log_write(
|
||||
isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_NETMGR,
|
||||
ISC_LOG_DEBUG(3),
|
||||
"throttling TCP connection, the other side is not "
|
||||
"reading the data, switching to uv_write()");
|
||||
sock->reading_throttled = true;
|
||||
isc__nm_stop_reading(sock);
|
||||
|
||||
r = uv_write(&req->uv_req.write, &sock->uv_handle.stream,
|
||||
&req->uvbuf, 1, tls_write_cb);
|
||||
if (r < 0) {
|
||||
@@ -1820,25 +1828,10 @@ tlsdns_maybe_restart_reading(isc_nmsocket_t *sock) {
|
||||
if (!sock->client && sock->reading_throttled &&
|
||||
!uv_is_active(&sock->uv_handle.handle))
|
||||
{
|
||||
/*
|
||||
* Restart reading if we have less data in the send queue than
|
||||
* the send buffer size, this means that the TCP client has
|
||||
* started reading some data again. Starting reading when we go
|
||||
* under the limit instead of waiting for all data has been
|
||||
* flushed allows faster recovery (in case there was a
|
||||
* congestion and now there isn't).
|
||||
*/
|
||||
size_t write_queue_size =
|
||||
uv_stream_get_write_queue_size(&sock->uv_handle.stream);
|
||||
if (write_queue_size < ISC_NETMGR_TCP_SENDBUF_SIZE) {
|
||||
isc_log_write(
|
||||
isc_lctx, ISC_LOGCATEGORY_GENERAL,
|
||||
ISC_LOGMODULE_NETMGR, ISC_LOG_DEBUG(3),
|
||||
"resuming TCP connection, the other side "
|
||||
"is reading the data again (%zu)",
|
||||
write_queue_size);
|
||||
sock->reading_throttled = false;
|
||||
isc__nm_start_reading(sock);
|
||||
isc_result_t result = isc__nm_process_sock_buffer(sock);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
atomic_store(&sock->reading, true);
|
||||
isc__nm_failed_read_cb(sock, result, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -333,6 +333,7 @@ client_senddone(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
|
||||
NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
|
||||
"send failed: %s",
|
||||
isc_result_totext(result));
|
||||
isc_nm_bad_request(handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user