mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-30 12:00:11 +01:00
connectivity: merge branch 'th/connectivity-resolve'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1176
This commit is contained in:
commit
721f0e75de
1 changed files with 160 additions and 46 deletions
|
|
@ -623,47 +623,73 @@ _timeout_cb(gpointer user_data)
|
|||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
easy_debug_enabled(void)
|
||||
{
|
||||
static int enabled = 0;
|
||||
int e;
|
||||
|
||||
/* libcurl debug logging can be useful, but is very verbose.
|
||||
* Only enable it when we have a certain environment variable set. */
|
||||
|
||||
again:
|
||||
e = g_atomic_int_get(&enabled);
|
||||
if (G_UNLIKELY(e == 0)) {
|
||||
e = _nm_utils_ascii_str_to_bool(g_getenv("NM_LOG_CONCHECK"), FALSE) ? 1 : -1;
|
||||
if (G_UNLIKELY(!g_atomic_int_compare_and_exchange(&enabled, 0, e)))
|
||||
goto again;
|
||||
}
|
||||
return e >= 0;
|
||||
}
|
||||
|
||||
static int
|
||||
easy_debug_cb(CURL *handle, curl_infotype type, char *data, size_t size, void *userptr)
|
||||
{
|
||||
NMConnectivityCheckHandle *cb_data = userptr;
|
||||
const char *escaped = NULL;
|
||||
gs_free char *to_free = NULL;
|
||||
NMConnectivityCheckHandle *cb_data = userptr;
|
||||
gs_free char *data_escaped = NULL;
|
||||
const char *msg;
|
||||
gboolean print_data = FALSE;
|
||||
|
||||
switch (type) {
|
||||
case CURLINFO_TEXT:
|
||||
escaped = nm_utils_buf_utf8safe_escape((char *) data,
|
||||
size,
|
||||
NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL,
|
||||
&to_free);
|
||||
_LOG2T("libcurl: == Info: %s", escaped ?: "");
|
||||
/* fall-through */
|
||||
default: /* in case a new one is introduced to shock us */
|
||||
return 0;
|
||||
|
||||
print_data = TRUE;
|
||||
msg = "== Info: ";
|
||||
break;
|
||||
case CURLINFO_DATA_OUT:
|
||||
_LOG2T("libcurl => Send data");
|
||||
return 0;
|
||||
msg = "=> Send data";
|
||||
break;
|
||||
case CURLINFO_SSL_DATA_OUT:
|
||||
_LOG2T("libcurl => Send SSL data");
|
||||
return 0;
|
||||
msg = "=> Send SSL data";
|
||||
break;
|
||||
case CURLINFO_HEADER_IN:
|
||||
_LOG2T("libcurl <= Recv header");
|
||||
return 0;
|
||||
msg = "<= Recv header";
|
||||
break;
|
||||
case CURLINFO_DATA_IN:
|
||||
_LOG2T("libcurl <= Recv data");
|
||||
return 0;
|
||||
msg = "<= Recv data";
|
||||
break;
|
||||
case CURLINFO_SSL_DATA_IN:
|
||||
_LOG2T("libcurl <= Recv SSL data");
|
||||
return 0;
|
||||
msg = "<= Recv SSL data";
|
||||
break;
|
||||
case CURLINFO_HEADER_OUT:
|
||||
escaped = nm_utils_buf_utf8safe_escape((char *) data,
|
||||
size,
|
||||
NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL,
|
||||
&to_free);
|
||||
_LOG2T("libcurl => Send header: %s", escaped ?: "");
|
||||
print_data = TRUE;
|
||||
msg = "=> Send header: ";
|
||||
return 0;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
_LOG2T("libcurl %s%s%s%s",
|
||||
msg,
|
||||
NM_PRINT_FMT_QUOTED(print_data,
|
||||
"[",
|
||||
(data_escaped = nm_utils_buf_utf8safe_escape_cp(
|
||||
data,
|
||||
size,
|
||||
NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL))
|
||||
?: "",
|
||||
"]",
|
||||
""));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -684,12 +710,14 @@ _idle_cb(gpointer user_data)
|
|||
|
||||
#if WITH_CONCHECK
|
||||
static void
|
||||
do_curl_request(NMConnectivityCheckHandle *cb_data)
|
||||
do_curl_request(NMConnectivityCheckHandle *cb_data, const char *hosts)
|
||||
{
|
||||
CURLM *mhandle;
|
||||
CURL *ehandle;
|
||||
long resolve;
|
||||
|
||||
_LOG2T("set curl resolve list to '%s'", hosts);
|
||||
|
||||
mhandle = curl_multi_init();
|
||||
if (!mhandle) {
|
||||
cb_data_complete(cb_data, NM_CONNECTIVITY_ERROR, "curl error");
|
||||
|
|
@ -703,6 +731,8 @@ do_curl_request(NMConnectivityCheckHandle *cb_data)
|
|||
return;
|
||||
}
|
||||
|
||||
cb_data->concheck.hosts = curl_slist_append(NULL, hosts);
|
||||
|
||||
cb_data->concheck.curl_mhandle = mhandle;
|
||||
cb_data->concheck.curl_ehandle = ehandle;
|
||||
cb_data->concheck.request_headers = curl_slist_append(NULL, "Connection: close");
|
||||
|
|
@ -739,7 +769,7 @@ do_curl_request(NMConnectivityCheckHandle *cb_data)
|
|||
curl_easy_setopt(ehandle, CURLOPT_RESOLVE, cb_data->concheck.hosts);
|
||||
curl_easy_setopt(ehandle, CURLOPT_IPRESOLVE, resolve);
|
||||
curl_easy_setopt(ehandle, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
|
||||
if (_LOGT_ENABLED()) {
|
||||
if (_LOGT_ENABLED() && easy_debug_enabled()) {
|
||||
curl_easy_setopt(ehandle, CURLOPT_DEBUGFUNCTION, easy_debug_cb);
|
||||
curl_easy_setopt(ehandle, CURLOPT_DEBUGDATA, cb_data);
|
||||
curl_easy_setopt(ehandle, CURLOPT_VERBOSE, 1L);
|
||||
|
|
@ -749,7 +779,93 @@ do_curl_request(NMConnectivityCheckHandle *cb_data)
|
|||
}
|
||||
|
||||
static void
|
||||
resolve_cb(GObject *object, GAsyncResult *res, gpointer user_data)
|
||||
system_resolver_resolve_cb(GObject *source_object, GAsyncResult *res, gpointer user_data)
|
||||
{
|
||||
nm_auto_str_buf NMStrBuf strbuf_hosts = NM_STR_BUF_INIT(0, FALSE);
|
||||
gs_free_error GError *resolv_error = NULL;
|
||||
GList *list;
|
||||
GList *iter;
|
||||
NMConnectivityCheckHandle *cb_data;
|
||||
|
||||
list = g_resolver_lookup_by_name_finish(G_RESOLVER(source_object), res, &resolv_error);
|
||||
|
||||
if (nm_utils_error_is_cancelled(resolv_error))
|
||||
return;
|
||||
|
||||
cb_data = user_data;
|
||||
|
||||
nm_assert(cb_data);
|
||||
nm_assert(NM_IS_CONNECTIVITY(cb_data->self));
|
||||
|
||||
if (resolv_error) {
|
||||
_LOG2D("failure to resolve name: %s", resolv_error->message);
|
||||
cb_data_complete(cb_data, NM_CONNECTIVITY_LIMITED, "resolve-error");
|
||||
return;
|
||||
}
|
||||
|
||||
for (iter = list; iter; iter = iter->next) {
|
||||
GInetAddress *a = iter->data;
|
||||
char str_addr[NM_UTILS_INET_ADDRSTRLEN];
|
||||
int addr_family;
|
||||
|
||||
switch (g_inet_address_get_family(a)) {
|
||||
case G_SOCKET_FAMILY_IPV4:
|
||||
addr_family = AF_INET;
|
||||
break;
|
||||
case G_SOCKET_FAMILY_IPV6:
|
||||
addr_family = AF_INET6;
|
||||
break;
|
||||
default:
|
||||
addr_family = AF_UNSPEC;
|
||||
break;
|
||||
}
|
||||
if (cb_data->addr_family != AF_UNSPEC && cb_data->addr_family != addr_family)
|
||||
continue;
|
||||
|
||||
if (strbuf_hosts.len == 0) {
|
||||
nm_str_buf_append_printf(&strbuf_hosts,
|
||||
"%s:%s:",
|
||||
cb_data->concheck.con_config->host,
|
||||
cb_data->concheck.con_config->port ?: "80");
|
||||
} else
|
||||
nm_str_buf_append_c(&strbuf_hosts, ',');
|
||||
|
||||
nm_str_buf_append(&strbuf_hosts,
|
||||
nm_utils_inet_ntop(addr_family, g_inet_address_to_bytes(a), str_addr));
|
||||
}
|
||||
|
||||
g_list_free_full(list, g_object_unref);
|
||||
|
||||
if (strbuf_hosts.len == 0) {
|
||||
_LOG2D("system resolver returned no usable IPv%c addresses",
|
||||
nm_utils_addr_family_to_char(cb_data->addr_family));
|
||||
cb_data_complete(cb_data, NM_CONNECTIVITY_LIMITED, "resolve-error");
|
||||
return;
|
||||
}
|
||||
|
||||
do_curl_request(cb_data, nm_str_buf_get_str(&strbuf_hosts));
|
||||
}
|
||||
|
||||
static void
|
||||
system_resolver_resolve(NMConnectivityCheckHandle *cb_data)
|
||||
{
|
||||
gs_unref_object GResolver *resolver = NULL;
|
||||
|
||||
_LOG2D("start request to '%s' (try resolving '%s' using system resolver)",
|
||||
cb_data->concheck.con_config->uri,
|
||||
cb_data->concheck.con_config->host);
|
||||
|
||||
resolver = g_resolver_get_default();
|
||||
|
||||
g_resolver_lookup_by_name_async(resolver,
|
||||
cb_data->concheck.con_config->host,
|
||||
cb_data->concheck.resolve_cancellable,
|
||||
system_resolver_resolve_cb,
|
||||
cb_data);
|
||||
}
|
||||
|
||||
static void
|
||||
systemd_resolved_resolve_cb(GObject *object, GAsyncResult *res, gpointer user_data)
|
||||
{
|
||||
NMConnectivityCheckHandle *cb_data;
|
||||
gs_unref_variant GVariant *result = NULL;
|
||||
|
|
@ -763,7 +879,7 @@ resolve_cb(GObject *object, GAsyncResult *res, gpointer user_data)
|
|||
nm_auto_str_buf NMStrBuf strbuf_hosts = NM_STR_BUF_INIT(0, FALSE);
|
||||
|
||||
result = g_dbus_connection_call_finish(G_DBUS_CONNECTION(object), res, &error);
|
||||
if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
if (nm_utils_error_is_cancelled(error))
|
||||
return;
|
||||
|
||||
cb_data = user_data;
|
||||
|
|
@ -771,9 +887,9 @@ resolve_cb(GObject *object, GAsyncResult *res, gpointer user_data)
|
|||
g_clear_object(&cb_data->concheck.resolve_cancellable);
|
||||
|
||||
if (!result) {
|
||||
/* Never mind. Just let do curl do its own resolving. */
|
||||
/* Never mind. Fallback to the system resolver. */
|
||||
_LOG2D("can't resolve a name via systemd-resolved: %s", error->message);
|
||||
do_curl_request(cb_data);
|
||||
system_resolver_resolve(cb_data);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -807,14 +923,14 @@ resolve_cb(GObject *object, GAsyncResult *res, gpointer user_data)
|
|||
|
||||
nm_str_buf_append(&strbuf_hosts, nm_utils_inet_ntop(addr_family, address_buf, str_addr));
|
||||
}
|
||||
if (strbuf_hosts.len > 0) {
|
||||
const char *s = nm_str_buf_get_str(&strbuf_hosts);
|
||||
|
||||
cb_data->concheck.hosts = curl_slist_append(NULL, s);
|
||||
_LOG2T("set curl resolve list to '%s'", s);
|
||||
if (strbuf_hosts.len == 0) {
|
||||
_LOG2D("systemd-resolve returned no usable IPv%c addresses",
|
||||
nm_utils_addr_family_to_char(cb_data->addr_family));
|
||||
cb_data_complete(cb_data, NM_CONNECTIVITY_LIMITED, "resolve-error");
|
||||
return;
|
||||
}
|
||||
|
||||
do_curl_request(cb_data);
|
||||
do_curl_request(cb_data, nm_str_buf_get_str(&strbuf_hosts));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -940,6 +1056,8 @@ nm_connectivity_check_start(NMConnectivity *self,
|
|||
}
|
||||
}
|
||||
|
||||
cb_data->concheck.resolve_cancellable = g_cancellable_new();
|
||||
|
||||
/* note that we pick up support for systemd-resolved right away when we need it.
|
||||
* We don't need to remember the setting, because we can (cheaply) check anew
|
||||
* on each request.
|
||||
|
|
@ -975,8 +1093,6 @@ nm_connectivity_check_start(NMConnectivity *self,
|
|||
return cb_data;
|
||||
}
|
||||
|
||||
cb_data->concheck.resolve_cancellable = g_cancellable_new();
|
||||
|
||||
g_dbus_connection_call(dbus_connection,
|
||||
"org.freedesktop.resolve1",
|
||||
"/org/freedesktop/resolve1",
|
||||
|
|
@ -991,17 +1107,15 @@ nm_connectivity_check_start(NMConnectivity *self,
|
|||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
cb_data->concheck.resolve_cancellable,
|
||||
resolve_cb,
|
||||
systemd_resolved_resolve_cb,
|
||||
cb_data);
|
||||
_LOG2D("start request to '%s' (try resolving '%s' using systemd-resolved)",
|
||||
cb_data->concheck.con_config->uri,
|
||||
cb_data->concheck.con_config->host);
|
||||
} else {
|
||||
_LOG2D("start request to '%s' (systemd-resolved not available)",
|
||||
cb_data->concheck.con_config->uri);
|
||||
do_curl_request(cb_data);
|
||||
return cb_data;
|
||||
}
|
||||
|
||||
system_resolver_resolve(cb_data);
|
||||
return cb_data;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue