diff -Nru network-manager-1.44.2/debian/NetworkManager.conf network-manager-1.44.2/debian/NetworkManager.conf --- network-manager-1.44.2/debian/NetworkManager.conf 2024-07-04 09:43:31.000000000 +0800 +++ network-manager-1.44.2/debian/NetworkManager.conf 2025-02-28 09:53:04.000000000 +0800 @@ -8,5 +8,5 @@ wifi.scan-rand-mac-address=no [connectivity] -uri=http://connectivity-check.ubuntu.com -interval=90 +uri=https://www.cnnic.net.cn +interval=45 diff -Nru network-manager-1.44.2/debian/changelog network-manager-1.44.2/debian/changelog --- network-manager-1.44.2/debian/changelog 2024-07-04 09:43:31.000000000 +0800 +++ network-manager-1.44.2/debian/changelog 2025-02-28 09:53:04.000000000 +0800 @@ -1,3 +1,12 @@ +network-manager (1.44.2-ok1.4) nile; urgency=medium + + * BUG:无 + * 需求:无 + * 其他改动说明:导入v11代码,同步连通性检测包 + * 其他改动影响域:无 + + -- dengtuo <dengtuo@kylinos.cn> Fri, 28 Feb 2025 09:53:04 +0800 + network-manager (1.44.2-ok1.3) nile; urgency=medium * No-change rebuild for netplan.io 1.0-ok3 diff -Nru network-manager-1.44.2/debian/control network-manager-1.44.2/debian/control --- network-manager-1.44.2/debian/control 2024-07-04 09:43:31.000000000 +0800 +++ network-manager-1.44.2/debian/control 2025-02-28 09:53:04.000000000 +0800 @@ -55,6 +55,7 @@ netplan.io (>= 0.106~) [!i386], polkitd | policykit-1, udev, + systemd-resolved, ${misc:Depends}, ${shlibs:Depends} Recommends: dnsmasq-base, diff -Nru network-manager-1.44.2/debian/patches/fix-network-manager.patch network-manager-1.44.2/debian/patches/fix-network-manager.patch --- network-manager-1.44.2/debian/patches/fix-network-manager.patch 1970-01-01 08:00:00.000000000 +0800 +++ network-manager-1.44.2/debian/patches/fix-network-manager.patch 2025-02-28 09:53:04.000000000 +0800 @@ -0,0 +1,1011 @@ +From: dengtuo <dengtuo@kylinos.cn> +Date: Fri, 28 Feb 2025 09:56:13 +0800 +Subject: =?utf-8?b?Zml4KG5ldHdvcmstbWFuYWdlcik6IOWQiOWFpeacgOaWsOS7o+eggQ==?= + =?utf-8?b?5Lul5Y+K6L+e6YCa5oCn5qOA5rWL5Luj56CB?= + +Description: none + +Log: none +--- + docs/api/html/NetworkManager.devhelp2 | 1 + + docs/api/html/nm-dbus-types.html | 17 ++- + docs/libnm/html/libnm-nm-dbus-interface.html | 9 +- + docs/libnm/html/libnm.devhelp2 | 1 + + introspection/org.freedesktop.NetworkManager.xml | 7 ++ + src/core/devices/nm-device.c | 9 ++ + src/core/nm-config-data.c | 49 +++++++++ + src/core/nm-config-data.h | 22 ++-- + src/core/nm-config.c | 44 +++++--- + src/core/nm-connectivity.c | 128 +++++++++++++++++++---- + src/core/nm-manager.c | 88 +++++++++++++++- + src/core/nm-manager.h | 1 + + src/libnm-base/nm-config-base.h | 1 + + src/libnm-client-impl/nm-client.c | 72 +++++++++++++ + src/libnm-client-public/nm-client.h | 4 + + src/libnm-core-aux-intern/nm-common-macros.h | 2 + + src/libnm-core-aux-intern/nm-libnm-core-utils.c | 2 + + src/libnm-core-public/nm-dbus-interface.h | 5 +- + src/libnm-core-public/nm-dbus-types.xml | 5 + + 19 files changed, 418 insertions(+), 49 deletions(-) + +diff --git a/docs/api/html/NetworkManager.devhelp2 b/docs/api/html/NetworkManager.devhelp2 +index 850eb5c..855cd00 100644 +--- a/docs/api/html/NetworkManager.devhelp2 ++++ b/docs/api/html/NetworkManager.devhelp2 +@@ -856,6 +856,7 @@ + <keyword type="constant" name="NM_CLIENT_PERMISSION_ENABLE_DISABLE_STATISTICS" link="nm-dbus-types.htmlnm-dbus-types.html#id-1.4.17.2.35.4.2.1.4.16.1.1id-1.4.17.2.35.4.2.1.4.16.1.2"/> + <keyword type="constant" name="NM_CLIENT_PERMISSION_ENABLE_DISABLE_CONNECTIVITY_CHECK" link="nm-dbus-types.htmlnm-dbus-types.html#id-1.4.17.2.35.4.2.1.4.17.1.1id-1.4.17.2.35.4.2.1.4.17.1.2"/> + <keyword type="constant" name="NM_CLIENT_PERMISSION_WIFI_SCAN" link="nm-dbus-types.htmlnm-dbus-types.html#id-1.4.17.2.35.4.2.1.4.18.1.1id-1.4.17.2.35.4.2.1.4.18.1.2"/> ++ <keyword type="constant" name="NM_CLIENT_PERMISSION_CONNECTIVITY_SPARE_CHECK" link="nm-dbus-types.htmlnm-dbus-types.html#id-1.4.17.2.35.4.2.1.4.19.1.1id-1.4.17.2.35.4.2.1.4.19.1.2"/> + <keyword type="constant" name="NM_CLIENT_PERMISSION_RESULT_UNKNOWN" link="nm-dbus-types.htmlnm-dbus-types.html#id-1.4.17.2.36.4.2.1.4.1.1.1id-1.4.17.2.36.4.2.1.4.1.1.2"/> + <keyword type="constant" name="NM_CLIENT_PERMISSION_RESULT_YES" link="nm-dbus-types.htmlnm-dbus-types.html#id-1.4.17.2.36.4.2.1.4.2.1.1id-1.4.17.2.36.4.2.1.4.2.1.2"/> + <keyword type="constant" name="NM_CLIENT_PERMISSION_RESULT_AUTH" link="nm-dbus-types.htmlnm-dbus-types.html#id-1.4.17.2.36.4.2.1.4.3.1.1id-1.4.17.2.36.4.2.1.4.3.1.2"/> +diff --git a/docs/api/html/nm-dbus-types.html b/docs/api/html/nm-dbus-types.html +index 287647e..ca5f966 100644 +--- a/docs/api/html/nm-dbus-types.html ++++ b/docs/api/html/nm-dbus-types.html +@@ -5257,6 +5257,21 @@ + </td> + <td class="auto-generated"> </td> + </tr> ++<tr> ++<td class="enum_member_name"> ++<p>NM_CLIENT_PERMISSION_CONNECTIVITY_SPARE_CHECK</p> ++<p></p> ++</td> ++<td class="enum_member_value"> ++<p>= <code class="literal">18</code></p> ++<p></p> ++</td> ++<td class="enum_member_description"> ++<p>controls connectivity spare check</p> ++<p></p> ++</td> ++<td class="auto-generated"> </td> ++</tr> + </tbody> + </table></div> + </div> +@@ -5563,4 +5578,4 @@ + <div class="footer"> + <hr>Generated by GTK-Doc V1.33.1</div> + </body> +-</html> +\ No newline at end of file ++</html> +diff --git a/docs/libnm/html/libnm-nm-dbus-interface.html b/docs/libnm/html/libnm-nm-dbus-interface.html +index 7516f13..a067cd4 100644 +--- a/docs/libnm/html/libnm-nm-dbus-interface.html ++++ b/docs/libnm/html/libnm-nm-dbus-interface.html +@@ -4074,6 +4074,13 @@ connectivity check can be enabled or disabled</p> + <td class="enum_member_annotations"> </td> + </tr> + <tr> ++<td class="enum_member_name"><p><a name="NM-CLIENT-PERMISSION-CONNECTIVITY-SPARE-CHECK:CAPS"></a>NM_CLIENT_PERMISSION_CONNECTIVITY_SPARE_CHECK</p></td> ++<td class="enum_member_description"> ++<p>controls connectivity spare check</p> ++</td> ++<td class="enum_member_annotations"> </td> ++</tr> ++<tr> + <td class="enum_member_name"><p><a name="NM-CLIENT-PERMISSION-LAST:CAPS"></a>NM_CLIENT_PERMISSION_LAST</p></td> + <td class="enum_member_description"> + <p>a reserved boundary value</p> +@@ -4289,4 +4296,4 @@ sub-option will trigger creation of an additional subflow to generate a full mes + <div class="footer"> + <hr>Generated by GTK-Doc V1.33.1</div> + </body> +-</html> +\ No newline at end of file ++</html> +diff --git a/docs/libnm/html/libnm.devhelp2 b/docs/libnm/html/libnm.devhelp2 +index 99b3359..5836d7c 100644 +--- a/docs/libnm/html/libnm.devhelp2 ++++ b/docs/libnm/html/libnm.devhelp2 +@@ -3803,6 +3803,7 @@ + <keyword type="constant" name="NM_CLIENT_PERMISSION_ENABLE_DISABLE_STATISTICS" link="libnm-nm-dbus-interface.html#NM-CLIENT-PERMISSION-ENABLE-DISABLE-STATISTICS:CAPS"/> + <keyword type="constant" name="NM_CLIENT_PERMISSION_ENABLE_DISABLE_CONNECTIVITY_CHECK" link="libnm-nm-dbus-interface.html#NM-CLIENT-PERMISSION-ENABLE-DISABLE-CONNECTIVITY-CHECK:CAPS"/> + <keyword type="constant" name="NM_CLIENT_PERMISSION_WIFI_SCAN" link="libnm-nm-dbus-interface.html#NM-CLIENT-PERMISSION-WIFI-SCAN:CAPS"/> ++ <keyword type="constant" name="NM_CLIENT_PERMISSION_CONNECTIVITY_SPARE_CHECK" link="libnm-nm-dbus-interface.html#NM-CLIENT-PERMISSION-CONNECTIVITY-SPARE-CHECK:CAPS"/> + <keyword type="constant" name="NM_CLIENT_PERMISSION_LAST" link="libnm-nm-dbus-interface.html#NM-CLIENT-PERMISSION-LAST:CAPS"/> + <keyword type="constant" name="NM_CLIENT_PERMISSION_RESULT_UNKNOWN" link="libnm-nm-dbus-interface.html#NM-CLIENT-PERMISSION-RESULT-UNKNOWN:CAPS"/> + <keyword type="constant" name="NM_CLIENT_PERMISSION_RESULT_YES" link="libnm-nm-dbus-interface.html#NM-CLIENT-PERMISSION-RESULT-YES:CAPS"/> +diff --git a/introspection/org.freedesktop.NetworkManager.xml b/introspection/org.freedesktop.NetworkManager.xml +index c92c801..8fea581 100644 +--- a/introspection/org.freedesktop.NetworkManager.xml ++++ b/introspection/org.freedesktop.NetworkManager.xml +@@ -560,6 +560,13 @@ + --> + <property name="ConnectivityCheckUri" type="s" access="read"/> + ++ <!-- ++ ConnectivityCheckUri: ++ ++ The URI that NetworkManager will hit to check if there is internet connectivity. ++ --> ++ <property name="ConnectivityCheckSpareUri" type="s" access="readwrite"/> ++ + <!-- + GlobalDnsConfiguration: + +diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c +index d121256..e777b73 100644 +--- a/src/core/devices/nm-device.c ++++ b/src/core/devices/nm-device.c +@@ -6047,6 +6047,15 @@ concheck_handle_complete(NMDeviceConnectivityHandle *handle, GError *error) + g_slice_free(NMDeviceConnectivityHandle, handle); + } + ++// 回调函数,用于处理HTTP响应 ++static size_t ++WriteCallback(void* contents, size_t size, size_t nmemb, char* response) ++{ ++ size_t totalSize = size * nmemb; ++ // _LOGD ("WriteCallback contents %s", contents); ++ return totalSize; ++} ++ + static void + concheck_cb(NMConnectivity *connectivity, + NMConnectivityCheckHandle *c_handle, +diff --git a/src/core/nm-config-data.c b/src/core/nm-config-data.c +index ed6d838..098e79a 100644 +--- a/src/core/nm-config-data.c ++++ b/src/core/nm-config-data.c +@@ -61,6 +61,7 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_CONFIG_MAIN_FILE, + PROP_KEYFILE_INTERN, + PROP_CONNECTIVITY_ENABLED, + PROP_CONNECTIVITY_URI, ++ PROP_CONNECTIVITY_SPARE_URI, + PROP_CONNECTIVITY_INTERVAL, + PROP_CONNECTIVITY_RESPONSE, + PROP_NO_AUTO_DEFAULT, ); +@@ -84,6 +85,7 @@ typedef struct { + struct { + gboolean enabled; + char *uri; ++ char *spare_uri; + char *response; + guint interval; + } connectivity; +@@ -296,6 +298,37 @@ nm_config_data_get_connectivity_uri(const NMConfigData *self) + return NM_CONFIG_DATA_GET_PRIVATE(self)->connectivity.uri; + } + ++const char * ++nm_config_data_get_connectivity_spare_uri () ++{ ++ GKeyFile *key_file = g_key_file_new(); ++ GError *error = NULL; ++ ++ // 从文件中加载配置 ++ gboolean result = g_key_file_load_from_file(key_file, "/var/lib/NetworkManager/device.state", G_KEY_FILE_NONE, &error); ++ if (!result) { ++ g_error_free(error); ++ g_key_file_free(key_file); ++ // return 1; ++ } ++ ++ const char* value_device = (char*)malloc(sizeof(char)*100); ++ ++ if (result){ ++ value_device = g_key_file_get_string(key_file, "CONNECTIVITY", "spareuri", &error); ++ if (error != NULL) ++ { ++ g_print("Error while reading key spareuri value: %s\n", error->message); ++ g_error_free(error); ++ g_key_file_free(key_file); ++ value_device = NULL; ++ } ++ }else { ++ value_device = NULL; ++ } ++ return value_device; ++} ++ + guint + nm_config_data_get_connectivity_interval(const NMConfigData *self) + { +@@ -2076,6 +2109,9 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) + case PROP_CONNECTIVITY_URI: + g_value_set_string(value, nm_config_data_get_connectivity_uri(self)); + break; ++ case PROP_CONNECTIVITY_SPARE_URI: ++ g_value_set_string(value, nm_config_data_get_connectivity_spare_uri()); ++ break; + case PROP_CONNECTIVITY_INTERVAL: + g_value_set_uint(value, nm_config_data_get_connectivity_interval(self)); + break; +@@ -2196,6 +2232,11 @@ constructed(GObject *object) + NM_CONFIG_KEYFILE_GROUP_CONNECTIVITY, + NM_CONFIG_KEYFILE_KEY_CONNECTIVITY_URI, + NULL)); ++ priv->connectivity.spare_uri = ++ nm_strstrip(g_key_file_get_string(priv->keyfile, ++ NM_CONFIG_KEYFILE_GROUP_CONNECTIVITY, ++ NM_CONFIG_KEYFILE_KEY_CONNECTIVITY_SPARE_URI, ++ NULL)); + priv->connectivity.response = g_key_file_get_string(priv->keyfile, + NM_CONFIG_KEYFILE_GROUP_CONNECTIVITY, + NM_CONFIG_KEYFILE_KEY_CONNECTIVITY_RESPONSE, +@@ -2331,6 +2372,7 @@ finalize(GObject *gobject) + g_free(priv->config_description); + + g_free(priv->connectivity.uri); ++ g_free(priv->connectivity.spare_uri); + g_free(priv->connectivity.response); + + g_slist_free_full(priv->no_auto_default.specs, g_free); +@@ -2404,6 +2446,13 @@ nm_config_data_class_init(NMConfigDataClass *config_class) + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + ++ obj_properties[PROP_CONNECTIVITY_SPARE_URI] = ++ g_param_spec_string(NM_CONFIG_DATA_CONNECTIVITY_SPARE_URI, ++ "", ++ "", ++ NULL, ++ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); ++ + obj_properties[PROP_CONNECTIVITY_URI] = + g_param_spec_string(NM_CONFIG_DATA_CONNECTIVITY_URI, + "", +diff --git a/src/core/nm-config-data.h b/src/core/nm-config-data.h +index 9e7a50f..333df72 100644 +--- a/src/core/nm-config-data.h ++++ b/src/core/nm-config-data.h +@@ -40,16 +40,17 @@ typedef enum { + #define NM_CONFIG_DATA_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_CONFIG_DATA, NMConfigDataClass)) + +-#define NM_CONFIG_DATA_CONFIG_MAIN_FILE "config-main-file" +-#define NM_CONFIG_DATA_CONFIG_DESCRIPTION "config-description" +-#define NM_CONFIG_DATA_KEYFILE_USER "keyfile-user" +-#define NM_CONFIG_DATA_KEYFILE_INTERN "keyfile-intern" +-#define NM_CONFIG_DATA_CONNECTIVITY_ENABLED "connectivity-enabled" +-#define NM_CONFIG_DATA_CONNECTIVITY_URI "connectivity-uri" +-#define NM_CONFIG_DATA_CONNECTIVITY_INTERVAL "connectivity-interval" +-#define NM_CONFIG_DATA_CONNECTIVITY_RESPONSE "connectivity-response" +-#define NM_CONFIG_DATA_NO_AUTO_DEFAULT "no-auto-default" +-#define NM_CONFIG_DATA_DNS_MODE "dns" ++#define NM_CONFIG_DATA_CONFIG_MAIN_FILE "config-main-file" ++#define NM_CONFIG_DATA_CONFIG_DESCRIPTION "config-description" ++#define NM_CONFIG_DATA_KEYFILE_USER "keyfile-user" ++#define NM_CONFIG_DATA_KEYFILE_INTERN "keyfile-intern" ++#define NM_CONFIG_DATA_CONNECTIVITY_ENABLED "connectivity-enabled" ++#define NM_CONFIG_DATA_CONNECTIVITY_URI "connectivity-uri" ++#define NM_CONFIG_DATA_CONNECTIVITY_SPARE_URI "connectivity-spare-uri" ++#define NM_CONFIG_DATA_CONNECTIVITY_INTERVAL "connectivity-interval" ++#define NM_CONFIG_DATA_CONNECTIVITY_RESPONSE "connectivity-response" ++#define NM_CONFIG_DATA_NO_AUTO_DEFAULT "no-auto-default" ++#define NM_CONFIG_DATA_DNS_MODE "dns" + + typedef enum { + NM_CONFIG_GET_VALUE_NONE = 0, +@@ -171,6 +172,7 @@ gint64 nm_config_data_get_value_int64(const NMConfigData *self, + char **nm_config_data_get_plugins(const NMConfigData *config_data, gboolean allow_default); + gboolean nm_config_data_get_connectivity_enabled(const NMConfigData *config_data); + const char *nm_config_data_get_connectivity_uri(const NMConfigData *config_data); ++const char *nm_config_data_get_connectivity_spare_uri(); + guint nm_config_data_get_connectivity_interval(const NMConfigData *config_data); + const char *nm_config_data_get_connectivity_response(const NMConfigData *config_data); + +diff --git a/src/core/nm-config.c b/src/core/nm-config.c +index b8df41b..e92e4b1 100644 +--- a/src/core/nm-config.c ++++ b/src/core/nm-config.c +@@ -42,6 +42,7 @@ struct NMConfigCmdLineOptions { + + gboolean is_debug; + char *connectivity_uri; ++ char *connectivity_spare_uri; + + /* We store interval as signed internally to track whether it's + * set or not via GOptionEntry +@@ -479,6 +480,7 @@ _nm_config_cmd_line_options_clear(NMConfigCmdLineOptions *cli) + cli->configure_and_quit = NM_CONFIG_CONFIGURE_AND_QUIT_DISABLED; + cli->is_debug = FALSE; + nm_clear_g_free(&cli->connectivity_uri); ++ nm_clear_g_free(&cli->connectivity_spare_uri); + nm_clear_g_free(&cli->connectivity_response); + cli->connectivity_interval = -1; + cli->first_start = FALSE; +@@ -492,19 +494,20 @@ _nm_config_cmd_line_options_copy(const NMConfigCmdLineOptions *cli, NMConfigCmdL + g_return_if_fail(cli != dst); + + _nm_config_cmd_line_options_clear(dst); +- dst->config_dir = g_strdup(cli->config_dir); +- dst->system_config_dir = g_strdup(cli->system_config_dir); +- dst->config_main_file = g_strdup(cli->config_main_file); +- dst->no_auto_default_file = g_strdup(cli->no_auto_default_file); +- dst->intern_config_file = g_strdup(cli->intern_config_file); +- dst->state_file = g_strdup(cli->state_file); +- dst->plugins = g_strdup(cli->plugins); +- dst->configure_and_quit = cli->configure_and_quit; +- dst->is_debug = cli->is_debug; +- dst->connectivity_uri = g_strdup(cli->connectivity_uri); +- dst->connectivity_response = g_strdup(cli->connectivity_response); +- dst->connectivity_interval = cli->connectivity_interval; +- dst->first_start = cli->first_start; ++ dst->config_dir = g_strdup(cli->config_dir); ++ dst->system_config_dir = g_strdup(cli->system_config_dir); ++ dst->config_main_file = g_strdup(cli->config_main_file); ++ dst->no_auto_default_file = g_strdup(cli->no_auto_default_file); ++ dst->intern_config_file = g_strdup(cli->intern_config_file); ++ dst->state_file = g_strdup(cli->state_file); ++ dst->plugins = g_strdup(cli->plugins); ++ dst->configure_and_quit = cli->configure_and_quit; ++ dst->is_debug = cli->is_debug; ++ dst->connectivity_uri = g_strdup(cli->connectivity_uri); ++ dst->connectivity_spare_uri = g_strdup(cli->connectivity_spare_uri); ++ dst->connectivity_response = g_strdup(cli->connectivity_response); ++ dst->connectivity_interval = cli->connectivity_interval; ++ dst->first_start = cli->first_start; + } + + NMConfigCmdLineOptions * +@@ -647,6 +650,13 @@ nm_config_cmd_line_options_add_to_entries(NMConfigCmdLineOptions *cli, GOptionCo + &cli->connectivity_uri, + N_("An http(s) address for checking internet connectivity"), + "http://example.com"}, ++ {"connectivity-spare-uri", ++ 0, ++ G_OPTION_FLAG_HIDDEN, ++ G_OPTION_ARG_STRING, ++ &cli->connectivity_spare_uri, ++ N_("An http(s) address for checking internet connectivity"), ++ "https://www.cmmoc.net.cn"}, + {"connectivity-interval", + 0, + G_OPTION_FLAG_HIDDEN, +@@ -873,7 +883,8 @@ static const ConfigGroup config_groups[] = { + .keys = NM_MAKE_STRV(NM_CONFIG_KEYFILE_KEY_CONNECTIVITY_ENABLED, + NM_CONFIG_KEYFILE_KEY_CONNECTIVITY_INTERVAL, + NM_CONFIG_KEYFILE_KEY_CONNECTIVITY_RESPONSE, +- NM_CONFIG_KEYFILE_KEY_CONNECTIVITY_URI, ), ++ NM_CONFIG_KEYFILE_KEY_CONNECTIVITY_URI, ++ NM_CONFIG_KEYFILE_KEY_CONNECTIVITY_SPARE_URI, ), + }, + { + .group = NM_CONFIG_KEYFILE_GROUP_KEYFILE, +@@ -1411,6 +1422,11 @@ read_entire_config(const NMConfigCmdLineOptions *cli, + NM_CONFIG_KEYFILE_GROUP_CONNECTIVITY, + "uri", + cli->connectivity_uri); ++ if (cli->connectivity_spare_uri && cli->connectivity_spare_uri[0]) ++ g_key_file_set_string(keyfile, ++ NM_CONFIG_KEYFILE_GROUP_CONNECTIVITY, ++ "spare-uri", ++ cli->connectivity_spare_uri); + if (cli->connectivity_interval >= 0) + g_key_file_set_integer(keyfile, + NM_CONFIG_KEYFILE_GROUP_CONNECTIVITY, +diff --git a/src/core/nm-connectivity.c b/src/core/nm-connectivity.c +index 92de44f..8a8f2ef 100644 +--- a/src/core/nm-connectivity.c ++++ b/src/core/nm-connectivity.c +@@ -24,6 +24,8 @@ + #include "dns/nm-dns-manager.h" + + #define HEADER_STATUS_ONLINE "X-NetworkManager-Status: online\r\n" ++#define HEADER_STATUS_KEEP_ALIVE "Connection: keep-alive\r\n" ++#define HEADER_STATUS_ACCEPT_RANGES "Accept-Ranges: byte\r\n" + + /*****************************************************************************/ + +@@ -53,6 +55,7 @@ nm_connectivity_state_to_string(NMConnectivityState state) + typedef struct { + guint ref_count; + char *uri; ++ char *spare_uri; + char *host; + char *port; + char *response; +@@ -112,6 +115,7 @@ typedef struct { + + bool enabled : 1; + bool uri_valid : 1; ++ bool spare_uri_valid : 1; + } NMConnectivityPrivate; + + struct _NMConnectivity { +@@ -181,6 +185,7 @@ _con_config_unref(ConConfig *con_config) + return; + + g_free(con_config->uri); ++ g_free(con_config->spare_uri); + g_free(con_config->host); + g_free(con_config->port); + g_free(con_config->response); +@@ -197,6 +202,62 @@ _con_config_get_response(const ConConfig *con_config) + + /*****************************************************************************/ + ++// 回调函数,用于处理HTTP响应 ++static size_t ++WriteCallback(void* contents, size_t size, size_t nmemb, char* response) { ++ size_t totalSize = size * nmemb; ++ // response->append((char*)contents, totalSize); ++ // _LOGD ("WriteCallback contents %s", contents); ++ return totalSize; ++} ++ ++static NMConnectivityState ++cb_data_complete_second_connectivity_check(NMConnectivityState state) ++{ ++ CURL* curl; ++ CURLcode res; ++ char* response; ++ ++ curl_global_init(CURL_GLOBAL_DEFAULT); ++ ++ curl = curl_easy_init(); ++ ++ const char* spare_uri = nm_config_data_get_connectivity_spare_uri(); ++ ++ if (curl) { ++ // 设置要访问的URL ++ curl_easy_setopt(curl, CURLOPT_URL, spare_uri == NULL ? "http://www.baidu.com/" : spare_uri); ++ // 设置接收HTTP响应的回调函数 ++ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); ++ // 将HTTP响应写入response字符串 ++ curl_easy_setopt(curl, CURLOPT_WRITEDATA, response); ++ ++ // 发送HTTP请求 ++ res = curl_easy_perform(curl); ++ // 检查请求是否成功 ++ if (res != CURLE_OK) { ++ ++ } else { ++ long httpCode; ++ // 获取HTTP状态码 ++ curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode); ++ _LOGD ("HTTP status code: %d", httpCode); ++ if (httpCode == 202 || httpCode == 200) ++ state = NM_CONNECTIVITY_FULL; ++ if (httpCode == 307 || httpCode == 302) ++ state = NM_CONNECTIVITY_PORTAL; ++ } ++ ++ // 清理curl句柄 ++ curl_easy_cleanup(curl); ++ } ++ ++ // 清理全局curl资源 ++ curl_global_cleanup(); ++ ++ return state; ++} ++ + static void + cb_data_complete(NMConnectivityCheckHandle *cb_data, + NMConnectivityState state, +@@ -363,10 +424,26 @@ _con_curl_check_connectivity(CURLM *mhandle, int sockfd, int ev_bitmask) + + response = _con_config_get_response(cb_data->concheck.con_config); + +- if (response[0] == '\0' +- && (curl_easy_getinfo(msg->easy_handle, CURLINFO_RESPONSE_CODE, &response_code) +- == CURLE_OK)) { +- if (response_code == 204) { ++ if (curl_easy_getinfo(msg->easy_handle, CURLINFO_RESPONSE_CODE, &response_code) == CURLE_OK) { ++ _LOGD ("curl easy getinfo success"); ++ if (response_code == 304) { ++ /*连通性检测网址https://www.cnnic.net.cn返回的状态码就是304*/ ++ cb_data_queue_completed (cb_data, ++ NM_CONNECTIVITY_FULL, ++ "as expected", ++ NULL); ++ continue; ++ } ++ ++ if (response_code == 307) { ++ /*portal认证一般返回状态码302或307*/ ++ cb_data_queue_completed (cb_data, ++ NM_CONNECTIVITY_PORTAL, ++ "redirect status code", ++ NULL); ++ continue; ++ } ++ if (response_code == 204 || response_code == 200 || response_code == 302) { + /* We expected an empty response, and we got a 204 response code (no content). + * We may or may not have received any content (we would ignore it). + * Anyway, the response_code 204 means we are good. */ +@@ -377,21 +454,22 @@ _con_curl_check_connectivity(CURLM *mhandle, int sockfd, int ev_bitmask) + continue; + } + +- if (response_code == 200 && cb_data->concheck.response_good_cnt == 0) { ++// if (response_code == 200 && cb_data->concheck.response_good_cnt == 0) { + /* we expected no response, and indeed we got an empty reply (with status code 200) */ +- cb_data_queue_completed(cb_data, +- NM_CONNECTIVITY_FULL, +- "empty response, as expected", +- NULL); +- continue; +- } ++// cb_data_queue_completed(cb_data, ++// NM_CONNECTIVITY_FULL, ++// "empty response, as expected", ++// NULL); ++// continue; ++// } + } + + /* If we get here, it means that easy_write_cb() didn't read enough + * bytes to be able to do a match, or that we were asking for no content + * (204 response code) and we actually got some. Either way, that is + * an indication of a captive portal */ +- cb_data_queue_completed(cb_data, NM_CONNECTIVITY_PORTAL, "unexpected short response", NULL); ++ //unconfirmed ++// cb_data_queue_completed(cb_data, NM_CONNECTIVITY_PORTAL, "unexpected short response", NULL); + } + + /* if we return a failure, we don't know what went wrong. It's likely serious, because +@@ -528,7 +606,7 @@ easy_header_cb(char *buffer, size_t size, size_t nitems, void *userdata) + } + + if (len >= sizeof(HEADER_STATUS_ONLINE) - 1 +- && !g_ascii_strncasecmp(buffer, HEADER_STATUS_ONLINE, sizeof(HEADER_STATUS_ONLINE) - 1)) { ++ && !g_ascii_strncasecmp(buffer, HEADER_STATUS_ACCEPT_RANGES, sizeof(HEADER_STATUS_ACCEPT_RANGES) - 1)) { + cb_data_queue_completed(cb_data, NM_CONNECTIVITY_FULL, "status header found", NULL); + return 0; + } +@@ -565,7 +643,7 @@ easy_write_cb(void *buffer, size_t size, size_t nmemb, void *userdata) + * Continue receiving... */ + cb_data->concheck.response_good_cnt += len; + +- if (cb_data->concheck.response_good_cnt > (gsize) (100 * 1024)) { ++// if (cb_data->concheck.response_good_cnt > (gsize) (100 * 1024)) { + /* we expect an empty response. We accept either + * 1) status code 204 and any response + * 2) status code 200 and an empty response. +@@ -577,12 +655,12 @@ easy_write_cb(void *buffer, size_t size, size_t nmemb, void *userdata) + * + * However, if we get an excessive amount of data, we put a stop on it + * and fail. */ +- cb_data_queue_completed(cb_data, +- NM_CONNECTIVITY_PORTAL, +- "unexpected non-empty response", +- NULL); +- return 0; +- } ++// cb_data_queue_completed(cb_data, ++// NM_CONNECTIVITY_PORTAL, ++// "unexpected non-empty response", ++// NULL); ++// return 0; ++// } + + return len; + } +@@ -757,7 +835,11 @@ do_curl_request(NMConnectivityCheckHandle *cb_data, const char *hosts) + g_warn_if_reached(); + } + +- curl_easy_setopt(ehandle, CURLOPT_URL, cb_data->concheck.con_config->uri); ++ const char* spare_uri = nm_config_data_get_connectivity_spare_uri(); ++ if (spare_uri == NULL) ++ spare_uri = cb_data->concheck.con_config->uri; ++ ++ curl_easy_setopt(ehandle, CURLOPT_URL, strlen(spare_uri) > 0 ? spare_uri : cb_data->concheck.con_config->uri); + curl_easy_setopt(ehandle, CURLOPT_WRITEFUNCTION, easy_write_cb); + curl_easy_setopt(ehandle, CURLOPT_WRITEDATA, cb_data); + curl_easy_setopt(ehandle, CURLOPT_HEADERFUNCTION, easy_header_cb); +@@ -1082,6 +1164,10 @@ nm_connectivity_check_start(NMConnectivity *self, + * is only one attempt to start the service. */ + has_systemd_resolved = !!nm_dns_manager_get_systemd_resolved(nm_dns_manager_get()); + ++ const char* spare_uri = nm_config_data_get_connectivity_spare_uri(); ++ if (spare_uri == NULL) ++ spare_uri = cb_data->concheck.con_config->uri; ++ + if (has_systemd_resolved) { + GDBusConnection *dbus_connection; + +diff --git a/src/core/nm-manager.c b/src/core/nm-manager.c +index 874591f..8c26842 100644 +--- a/src/core/nm-manager.c ++++ b/src/core/nm-manager.c +@@ -164,6 +164,7 @@ NM_GOBJECT_PROPERTIES_DEFINE(NMManager, + PROP_CONNECTIVITY_CHECK_AVAILABLE, + PROP_CONNECTIVITY_CHECK_ENABLED, + PROP_CONNECTIVITY_CHECK_URI, ++ PROP_CONNECTIVITY_CHECK_SPARE_URI, + PROP_PRIMARY_CONNECTION, + PROP_PRIMARY_CONNECTION_TYPE, + PROP_ACTIVATING_CONNECTION, +@@ -8295,7 +8296,9 @@ _dbus_set_property_audit_log_get_args(NMDBusObject *obj, + if (NM_IN_STRSET(property_name, NM_MANAGER_GLOBAL_DNS_CONFIGURATION)) { + return NM_MANAGER_GLOBAL_DNS_CONFIGURATION; + } +- ++ if (NM_IN_STRSET(property_name, NM_MANAGER_CONNECTIVITY_CHECK_SPARE_URI)) { ++ return NM_MANAGER_CONNECTIVITY_CHECK_SPARE_URI; ++ } + return nm_assert_unreachable_val("???"); + } + +@@ -8742,6 +8745,69 @@ nm_manager_unblock_failed_ovs_interfaces(NMManager *self) + + /*****************************************************************************/ + ++static void ++nm_manager_set_connectivity_check_spare_uri (NMManager *self,const char *spare_uri) ++{ ++ GKeyFile *key_file = g_key_file_new(); ++ GError *error = NULL; ++ NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); ++ NMDevice *device; ++ ConnectivityCheckData *data; ++ ++ data = g_slice_new (ConnectivityCheckData); ++ data->self = g_object_ref (self); ++ ++ gboolean file_exists = g_file_test("/var/lib/NetworkManager/device.state", G_FILE_TEST_EXISTS); ++ ++ if (file_exists){ ++ // 从文件中加载配置 ++ gboolean result = g_key_file_load_from_file(key_file, "/var/lib/NetworkManager/device.state", G_KEY_FILE_NONE, &error); ++ if (!result) { ++ g_print("Failed to load config file: %s\n", error->message); ++ g_error_free(error); ++ g_key_file_free(key_file); ++ return; ++ } ++ ++ _LOGI (LOGD_CONCHECK, "Current Value Of Spareuri %s\n", spare_uri); ++ ++ //修改spareuri值 ++ g_key_file_set_string(key_file, "CONNECTIVITY", "spareuri", spare_uri); ++ ++ // 保存配置到文件 ++ result = g_key_file_save_to_file(key_file, "/var/lib/NetworkManager/device.state", &error); ++ if (!result) { ++ g_print("Failed to save config file: %s\n", error->message); ++ g_error_free(error); ++ } ++ ++ g_key_file_free(key_file); ++ c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst) { ++ nm_device_check_connectivity (device, AF_INET, device_connectivity_done, data); ++ } ++ return; ++ }else{ ++ //首次设置spareuri,没有device.state文件时 ++ _LOGI (LOGD_CONCHECK, "Current Value Of Spareuri %s\n", spare_uri); ++ g_key_file_set_string(key_file, "CONNECTIVITY", "spareuri", spare_uri); ++ ++ // 保存配置到文件 ++ gboolean save_result = g_key_file_save_to_file(key_file, "/var/lib/NetworkManager/device.state", &error); ++ if (!save_result) { ++ g_print("Failed to save config file: %s\n", error->message); ++ g_error_free(error); ++ } ++ ++ g_key_file_free(key_file); ++ c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst) { ++ nm_device_check_connectivity (device, AF_INET, device_connectivity_done, data); ++ } ++ return; ++ } ++} ++ ++/*****************************************************************************/ ++ + void + nm_manager_set_capability(NMManager *self, NMCapability cap) + { +@@ -9075,6 +9141,10 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) + config_data = nm_config_get_data(priv->config); + g_value_set_string(value, nm_config_data_get_connectivity_uri(config_data)); + break; ++ case PROP_CONNECTIVITY_CHECK_SPARE_URI: ++ config_data = nm_config_get_data(priv->config); ++ g_value_set_string(value, nm_config_data_get_connectivity_spare_uri()); ++ break; + case PROP_PRIMARY_CONNECTION: + nm_dbus_utils_g_value_set_object_path(value, priv->primary_connection); + break; +@@ -9147,6 +9217,9 @@ set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *ps + case PROP_CONNECTIVITY_CHECK_ENABLED: + nm_config_set_connectivity_check_enabled(priv->config, g_value_get_boolean(value)); + break; ++ case PROP_CONNECTIVITY_CHECK_SPARE_URI: ++ nm_manager_set_connectivity_check_spare_uri(NM_MANAGER (object), g_value_get_string(value)); ++ break; + case PROP_GLOBAL_DNS_CONFIGURATION: + dns_config = nm_global_dns_config_from_dbus(value, &error); + if (!error) +@@ -9561,6 +9634,12 @@ static const NMDBusInterfaceInfoExtended interface_info_manager = { + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("ConnectivityCheckUri", + "s", + NM_MANAGER_CONNECTIVITY_CHECK_URI), ++ NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READWRITABLE( ++ "ConnectivityCheckSpareUri", ++ "s", ++ NM_MANAGER_CONNECTIVITY_CHECK_SPARE_URI, ++ NM_AUTH_PERMISSION_CONNECTIVITY_SPARE_CHECK, ++ NM_AUDIT_OP_NET_CONTROL), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READWRITABLE( + "GlobalDnsConfiguration", + "a{sv}", +@@ -9724,6 +9803,13 @@ nm_manager_class_init(NMManagerClass *manager_class) + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + ++ obj_properties[PROP_CONNECTIVITY_CHECK_SPARE_URI] = ++ g_param_spec_string(NM_MANAGER_CONNECTIVITY_CHECK_SPARE_URI, ++ "", ++ "", ++ NULL, ++ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); ++ + obj_properties[PROP_PRIMARY_CONNECTION] = + g_param_spec_string(NM_MANAGER_PRIMARY_CONNECTION, + "", +diff --git a/src/core/nm-manager.h b/src/core/nm-manager.h +index 3028eb7..94614f1 100644 +--- a/src/core/nm-manager.h ++++ b/src/core/nm-manager.h +@@ -37,6 +37,7 @@ + #define NM_MANAGER_CONNECTIVITY_CHECK_AVAILABLE "connectivity-check-available" + #define NM_MANAGER_CONNECTIVITY_CHECK_ENABLED "connectivity-check-enabled" + #define NM_MANAGER_CONNECTIVITY_CHECK_URI "connectivity-check-uri" ++#define NM_MANAGER_CONNECTIVITY_CHECK_SPARE_URI "connectivity-check-spare-uri" + #define NM_MANAGER_PRIMARY_CONNECTION "primary-connection" + #define NM_MANAGER_PRIMARY_CONNECTION_TYPE "primary-connection-type" + #define NM_MANAGER_ACTIVATING_CONNECTION "activating-connection" +diff --git a/src/libnm-base/nm-config-base.h b/src/libnm-base/nm-config-base.h +index c90efc1..8d3f1c2 100644 +--- a/src/libnm-base/nm-config-base.h ++++ b/src/libnm-base/nm-config-base.h +@@ -47,6 +47,7 @@ + #define NM_CONFIG_KEYFILE_KEY_CONNECTIVITY_INTERVAL "interval" + #define NM_CONFIG_KEYFILE_KEY_CONNECTIVITY_RESPONSE "response" + #define NM_CONFIG_KEYFILE_KEY_CONNECTIVITY_URI "uri" ++#define NM_CONFIG_KEYFILE_KEY_CONNECTIVITY_SPARE_URI "spare-uri" + + #define NM_CONFIG_KEYFILE_KEY_KEYFILE_PATH "path" + #define NM_CONFIG_KEYFILE_KEY_KEYFILE_UNMANAGED_DEVICES "unmanaged-devices" +diff --git a/src/libnm-client-impl/nm-client.c b/src/libnm-client-impl/nm-client.c +index f3ab6d6..b5fc383 100644 +--- a/src/libnm-client-impl/nm-client.c ++++ b/src/libnm-client-impl/nm-client.c +@@ -203,6 +203,7 @@ NM_GOBJECT_PROPERTIES_DEFINE(NMClient, + PROP_ACTIVE_CONNECTIONS, + PROP_CONNECTIVITY, + PROP_CONNECTIVITY_CHECK_URI, ++ PROP_CONNECTIVITY_CHECK_SPARE_URI, + PROP_CONNECTIVITY_CHECK_AVAILABLE, + PROP_CONNECTIVITY_CHECK_ENABLED, + PROP_PRIMARY_CONNECTION, +@@ -304,6 +305,7 @@ typedef struct { + NMLDBusPropertyO property_o[_PROPERTY_O_IDX_NM_NUM]; + NMLDBusPropertyAO property_ao[_PROPERTY_AO_IDX_NM_NUM]; + char *connectivity_check_uri; ++ char *connectivity_check_spare_uri; + char *version; + guint32 *capabilities_arr; + guint32 *version_info_arr; +@@ -4443,6 +4445,27 @@ nm_client_connectivity_check_set_enabled(NMClient *client, gboolean enabled) + enabled); + } + ++/** ++ * nm_client_connectivity_check_set_enabled: ++ * @client: a #NMClient ++ * @spare_uri: connectivity check spare uri ++ * ++ * ++ * Since: 1.10 ++ */ ++void ++nm_client_connectivity_check_set_spare_uri(NMClient *client, const char * spare_uri) ++{ ++ g_return_if_fail(NM_IS_CLIENT(client)); ++ ++ _nm_client_set_property_sync_legacy(client, ++ NM_DBUS_PATH, ++ NM_DBUS_INTERFACE, ++ "ConnectivityCheckSpareUri", ++ "b", ++ spare_uri); ++} ++ + /** + * nm_client_connectivity_check_get_uri: + * @client: a #NMClient +@@ -4462,6 +4485,25 @@ nm_client_connectivity_check_get_uri(NMClient *client) + return NM_CLIENT_GET_PRIVATE(client)->nm.connectivity_check_uri; + } + ++/** ++ * nm_client_connectivity_check_get_spare_uri: ++ * @client: a #NMClient ++ * ++ * Get the spare-URI that will be queried to determine if there is internet ++ * connectivity. ++ * ++ * Returns: (transfer none): the connectivity URI in use ++ * ++ * Since: 1.20 ++ */ ++const char * ++nm_client_connectivity_check_get_spare_uri(NMClient *client) ++{ ++ g_return_val_if_fail(NM_IS_CLIENT(client), NULL); ++ ++ return NM_CLIENT_GET_PRIVATE(client)->nm.connectivity_check_spare_uri; ++} ++ + /** + * nm_client_get_logging: + * @client: a #NMClient +@@ -7580,6 +7622,9 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) + case PROP_CONNECTIVITY_CHECK_URI: + g_value_set_string(value, nm_client_connectivity_check_get_uri(self)); + break; ++ case PROP_CONNECTIVITY_CHECK_SPARE_URI: ++ g_value_set_string(value, nm_client_connectivity_check_get_spare_uri(self)); ++ break; + case PROP_PRIMARY_CONNECTION: + g_value_set_object(value, nm_client_get_primary_connection(self)); + break; +@@ -7656,6 +7701,7 @@ set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *ps + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE(self); + gboolean b; + guint v_uint; ++ char *spare_uri; + + switch (prop_id) { + case PROP_INSTANCE_FLAGS: +@@ -7730,6 +7776,13 @@ set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *ps + /* Let the property value flip when we get the change signal from NM */ + } + break; ++ case PROP_CONNECTIVITY_CHECK_SPARE_URI: ++ spare_uri = g_value_get_string(value); ++ if (priv->nm.connectivity_check_spare_uri != spare_uri) { ++ nm_client_connectivity_check_set_spare_uri(self, spare_uri); ++ /* Let the property value flip when we get the change signal from NM */ ++ } ++ break; + case PROP_WIMAX_ENABLED: + break; + default: +@@ -8045,6 +8098,7 @@ dispose(GObject *object) + nml_dbus_property_ao_clear_many(priv->nm.property_ao, G_N_ELEMENTS(priv->nm.property_ao), NULL); + + nm_clear_g_free(&priv->nm.connectivity_check_uri); ++ nm_clear_g_free(&priv->nm.connectivity_check_spare_uri); + nm_clear_g_free(&priv->nm.version); + + nml_dbus_property_ao_clear(&priv->settings.connections, NULL); +@@ -8137,6 +8191,10 @@ const NMLDBusMetaIface _nml_dbus_meta_iface_nm = NML_DBUS_META_IFACE_INIT_PROP( + PROP_CONNECTIVITY_CHECK_URI, + NMClient, + _priv.nm.connectivity_check_uri), ++ NML_DBUS_META_PROPERTY_INIT_S("ConnectivityCheckSpareUri", ++ PROP_CONNECTIVITY_CHECK_SPARE_URI, ++ NMClient, ++ _priv.nm.connectivity_check_spare_uri), + NML_DBUS_META_PROPERTY_INIT_AO_PROP("Devices", + PROP_DEVICES, + NMClient, +@@ -8536,6 +8594,20 @@ nm_client_class_init(NMClientClass *client_class) + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + ++ /** ++ * NMClient:connectivity-check-spare-uri: ++ * ++ * The used spare-URI for connectivity checking. ++ * ++ * Since: 1.22 ++ **/ ++ obj_properties[PROP_CONNECTIVITY_CHECK_SPARE_URI] = ++ g_param_spec_string(NM_CLIENT_CONNECTIVITY_CHECK_SPARE_URI, ++ "", ++ "", ++ NULL, ++ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); ++ + /** + * NMClient:primary-connection: + * +diff --git a/src/libnm-client-public/nm-client.h b/src/libnm-client-public/nm-client.h +index 9d54827..eb93a17 100644 +--- a/src/libnm-client-public/nm-client.h ++++ b/src/libnm-client-public/nm-client.h +@@ -74,6 +74,7 @@ _NM_DEPRECATED_SYNC_WRITABLE_PROPERTY + #define NM_CLIENT_ACTIVE_CONNECTIONS "active-connections" + #define NM_CLIENT_CONNECTIVITY "connectivity" + #define NM_CLIENT_CONNECTIVITY_CHECK_URI "connectivity-check-uri" ++#define NM_CLIENT_CONNECTIVITY_CHECK_SPARE_URI "connectivity-check-spare-uri" + #define NM_CLIENT_CONNECTIVITY_CHECK_AVAILABLE "connectivity-check-available" + + _NM_DEPRECATED_SYNC_WRITABLE_PROPERTY +@@ -249,6 +250,9 @@ void nm_client_connectivity_check_set_enabled(NMClient *client, gboolean enabled + NM_AVAILABLE_IN_1_20 + const char *nm_client_connectivity_check_get_uri(NMClient *client); + ++NM_AVAILABLE_IN_1_20 ++const char *nm_client_connectivity_check_get_spare_uri(NMClient *client); ++ + _NM_DEPRECATED_SYNC_METHOD + gboolean nm_client_get_logging(NMClient *client, char **level, char **domains, GError **error); + +diff --git a/src/libnm-core-aux-intern/nm-common-macros.h b/src/libnm-core-aux-intern/nm-common-macros.h +index c452b7d..b021600 100644 +--- a/src/libnm-core-aux-intern/nm-common-macros.h ++++ b/src/libnm-core-aux-intern/nm-common-macros.h +@@ -32,6 +32,8 @@ + "org.freedesktop.NetworkManager.enable-disable-statistics" + #define NM_AUTH_PERMISSION_ENABLE_DISABLE_CONNECTIVITY_CHECK \ + "org.freedesktop.NetworkManager.enable-disable-connectivity-check" ++#define NM_AUTH_PERMISSION_CONNECTIVITY_SPARE_CHECK \ ++ "org.freedesktop.NetworkManager.connectivity-spare-check" + #define NM_AUTH_PERMISSION_WIFI_SCAN "org.freedesktop.NetworkManager.wifi.scan" + + #define NM_CLONED_MAC_PRESERVE "preserve" +diff --git a/src/libnm-core-aux-intern/nm-libnm-core-utils.c b/src/libnm-core-aux-intern/nm-libnm-core-utils.c +index 3e317e5..7d25fb9 100644 +--- a/src/libnm-core-aux-intern/nm-libnm-core-utils.c ++++ b/src/libnm-core-aux-intern/nm-libnm-core-utils.c +@@ -287,6 +287,7 @@ nm_utils_vlan_priority_map_parse_str(NMVlanPriorityMap map_type, + + const char *const nm_auth_permission_names_by_idx[NM_CLIENT_PERMISSION_LAST] = { + [NM_CLIENT_PERMISSION_CHECKPOINT_ROLLBACK - 1] = NM_AUTH_PERMISSION_CHECKPOINT_ROLLBACK, ++ [NM_CLIENT_PERMISSION_CONNECTIVITY_SPARE_CHECK - 1] = NM_AUTH_PERMISSION_CONNECTIVITY_SPARE_CHECK, + [NM_CLIENT_PERMISSION_ENABLE_DISABLE_CONNECTIVITY_CHECK - 1] = + NM_AUTH_PERMISSION_ENABLE_DISABLE_CONNECTIVITY_CHECK, + [NM_CLIENT_PERMISSION_ENABLE_DISABLE_NETWORK - 1] = NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK, +@@ -311,6 +312,7 @@ const char *const nm_auth_permission_names_by_idx[NM_CLIENT_PERMISSION_LAST] = { + + const NMClientPermission nm_auth_permission_sorted[NM_CLIENT_PERMISSION_LAST] = { + NM_CLIENT_PERMISSION_CHECKPOINT_ROLLBACK, ++ NM_CLINET_PERMISSION_CONNECTIVITY_SPARE_CHECK, + NM_CLIENT_PERMISSION_ENABLE_DISABLE_CONNECTIVITY_CHECK, + NM_CLIENT_PERMISSION_ENABLE_DISABLE_NETWORK, + NM_CLIENT_PERMISSION_ENABLE_DISABLE_STATISTICS, +diff --git a/src/libnm-core-public/nm-dbus-interface.h b/src/libnm-core-public/nm-dbus-interface.h +index b490e3b..97226f6 100644 +--- a/src/libnm-core-public/nm-dbus-interface.h ++++ b/src/libnm-core-public/nm-dbus-interface.h +@@ -1285,6 +1285,8 @@ typedef enum /*< flags >*/ { + * @NM_CLIENT_PERMISSION_ENABLE_DISABLE_CONNECTIVITY_CHECK: controls whether + * connectivity check can be enabled or disabled + * @NM_CLIENT_PERMISSION_WIFI_SCAN: controls whether wifi scans can be performed ++ * @NM_CLIENT_PERMISSION_CONNECTIVITY_SPARE_CHECK: controls connectivity spare ++ * check + * @NM_CLIENT_PERMISSION_LAST: a reserved boundary value + * + * #NMClientPermission values indicate various permissions that NetworkManager +@@ -1309,8 +1311,9 @@ typedef enum { + NM_CLIENT_PERMISSION_ENABLE_DISABLE_STATISTICS = 15, + NM_CLIENT_PERMISSION_ENABLE_DISABLE_CONNECTIVITY_CHECK = 16, + NM_CLIENT_PERMISSION_WIFI_SCAN = 17, ++ NM_CLIENT_PERMISSION_CONNECTIVITY_SPARE_CHECK = 18, + +- NM_CLIENT_PERMISSION_LAST = 17, ++ NM_CLIENT_PERMISSION_LAST = 18, + } NMClientPermission; + + /** +diff --git a/src/libnm-core-public/nm-dbus-types.xml b/src/libnm-core-public/nm-dbus-types.xml +index d5ac04b..383a872 100644 +--- a/src/libnm-core-public/nm-dbus-types.xml ++++ b/src/libnm-core-public/nm-dbus-types.xml +@@ -2197,6 +2197,11 @@ + <entry role="enum_member_value"><para>= <literal>17</literal></para><para></para></entry> + <entry role="enum_member_description"><para>controls whether wifi scans can be performed</para><para></para></entry> + </row> ++ <row role="constant"> ++ <entry role="enum_member_name"><para>NM_CLIENT_PERMISSION_CONNECTIVITY_SPARE_CHECK</para><para></para></entry> ++ <entry role="enum_member_value"><para>= <literal>18</literal></para><para></para></entry> ++ <entry role="enum_member_description"><para>controls connectivity spare check</para><para></para></entry> ++ </row> + </tbody> + </tgroup> + </informaltable> diff -Nru network-manager-1.44.2/debian/patches/series network-manager-1.44.2/debian/patches/series --- network-manager-1.44.2/debian/patches/series 2024-07-04 09:43:31.000000000 +0800 +++ network-manager-1.44.2/debian/patches/series 2025-02-28 09:53:04.000000000 +0800 @@ -1 +1,2 @@ 24.patch +fix-network-manager.patch