From 57a94fec477a3fd4518081d9bf6fd3df1164f6b0 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 21 Mar 2026 23:06:02 +0100 Subject: [PATCH] multi.h: add CURLMNWC_CLEAR_ALL The two bitmask constants for *CLEAR_DNS and *CLEAR_CONNS were duplicates (both set to 1), so they cannot be distinguished and both actions fire. This shipped in public releases since 8.16.0 to and include 8.19.0. This fix adds CURLMNWC_CLEAR_ALL to be the new 1, and it now implies all bits. The DNS and CONNS defines get two new bits (2, 4). Follow-up to 55c045c86338bfcc1de676c496f Found by Codex Security Closes #20968 --- docs/libcurl/opts/CURLMOPT_NETWORK_CHANGED.md | 33 ++++++++++--------- docs/libcurl/symbols-in-versions | 1 + include/curl/multi.h | 20 ++++++----- lib/multi.c | 5 +++ 4 files changed, 36 insertions(+), 23 deletions(-) diff --git a/docs/libcurl/opts/CURLMOPT_NETWORK_CHANGED.md b/docs/libcurl/opts/CURLMOPT_NETWORK_CHANGED.md index a38a9a83ba..a2a44c359d 100644 --- a/docs/libcurl/opts/CURLMOPT_NETWORK_CHANGED.md +++ b/docs/libcurl/opts/CURLMOPT_NETWORK_CHANGED.md @@ -27,30 +27,33 @@ CURLMcode curl_multi_setopt(CURLM *handle, CURLMOPT_NETWORK_CHANGED, # DESCRIPTION -Pass a long with a bitmask to tell libcurl how the multi -handle should react. The following values in the mask are -defined. All bits not mentioned are reserved for future -extensions. +Pass a long with a bitmask to tell libcurl how the multi handle should react. +The following values in the mask are defined. All bits not mentioned are +reserved for future extensions. -This option can be set at any time and repeatedly. Each call only -affects the *currently* cached connections and DNS information. -Any connection created or DNS information added afterwards is -cached the usual way again. Phrasing it another way: the option is -not persisted but setting it serves as a "trigger" +This option can be set at any time and repeatedly. Each call only affects the +*currently* cached connections and DNS information. Any connection created or +DNS information added afterwards is cached the usual way again. Phrasing it +another way: the option is not persisted but setting it serves as a "trigger" to clear the caches. -The call affects only the connection and DNS cache of the multi handle -itself and not the ones owned by SHARE handles. +The call affects only the connection and DNS cache of the multi handle itself +and not the ones owned by SHARE handles. + +## CURLMNWC_CLEAR_ALL + +Clear everything. (Added in 8.20.0) ## CURLMNWC_CLEAR_CONNS -No longer reuse any existing connection in the multi handle's -connection cache. This closes all connections that are not in use. -Ongoing transfers continue on the connections they operate on. +No longer reuse any existing connection in the multi handle's connection +cache. This closes all connections that are not in use. Ongoing transfers +continue on the connections they operate on. ## CURLMNWC_CLEAR_DNS -Clear the multi handle's DNS cache. +Clear the multi handle's DNS cache. Ongoing transfers keep using their already +resolved addresses, but future name resolutions are performed again. # DEFAULT diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions index 4e28506df2..987d4304f2 100644 --- a/docs/libcurl/symbols-in-versions +++ b/docs/libcurl/symbols-in-versions @@ -561,6 +561,7 @@ CURLMINFO_XFERS_PENDING 8.16.0 CURLMINFO_XFERS_RUNNING 8.16.0 CURLMNOTIFY_EASY_DONE 8.17.0 CURLMNOTIFY_INFO_READ 8.17.0 +CURLMNWC_CLEAR_ALL 8.20.0 CURLMNWC_CLEAR_CONNS 8.16.0 CURLMNWC_CLEAR_DNS 8.16.0 CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE 7.30.0 diff --git a/include/curl/multi.h b/include/curl/multi.h index c41981ee9c..7baea3778b 100644 --- a/include/curl/multi.h +++ b/include/curl/multi.h @@ -408,15 +408,19 @@ typedef enum { /* Definition of bits for the CURLMOPT_NETWORK_CHANGED argument: */ -/* - CURLMNWC_CLEAR_CONNS tells libcurl to prevent further reuse of existing - connections. Connections that are idle are closed. Ongoing transfers - do continue with the connection they have. */ -#define CURLMNWC_CLEAR_CONNS (1L << 0) +/* - CURLMNWC_CLEAR_ALL tells libcurl to clear "everything" that could be + associated with this network, including both connections and DNS data. */ +#define CURLMNWC_CLEAR_ALL (1L << 0) -/* - CURLMNWC_CLEAR_DNS tells libcurl to prevent further reuse of existing - connections. Connections that are idle are closed. Ongoing transfers - do continue with the connection they have. */ -#define CURLMNWC_CLEAR_DNS (1L << 0) +/* - CURLMNWC_CLEAR_CONNS tells libcurl to prevent further reuse of existing + connections. Connections that are idle are closed. Ongoing transfers do + continue with the connection they have. */ +#define CURLMNWC_CLEAR_CONNS (1L << 1) + +/* - CURLMNWC_CLEAR_DNS tells libcurl to clear the DNS cache associated with + this multi handle. Ongoing transfers keep using their already resolved + addresses, but future name resolutions are performed again. */ +#define CURLMNWC_CLEAR_DNS (1L << 2) /* * Name: curl_multi_setopt() diff --git a/lib/multi.c b/lib/multi.c index a620dfa6be..482663edd5 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -3328,6 +3328,11 @@ CURLMcode curl_multi_setopt(CURLM *m, CURLMoption option, ...) } case CURLMOPT_NETWORK_CHANGED: { long val = va_arg(param, long); + if(val & CURLMNWC_CLEAR_ALL) + /* In the beginning, all values available to set were 1 by mistake. We + converted this to mean "all", thus setting all the bits + automatically */ + val = CURLMNWC_CLEAR_DNS | CURLMNWC_CLEAR_CONNS; if(val & CURLMNWC_CLEAR_DNS) { Curl_dnscache_clear(multi->admin); }